TI中文支持网
TI专业的中文技术问题搜集分享网站

CC2530内部flash数据丢失问题求教

 我这里使用的TI的CC2530开发的产品中使用了内部的flash存储的数据最近发现有丢失现象,协议栈使用的是Zstack-CC2530-2.3.0-1.4.0,flash读写函数使用的是协议栈中提供的osal_nv_write(),osal_nv_read()和osal_nv_item_init()函数,在调用osal_nv_write()和osal_nv_read()之前都先调用的osal_nv_item_init(),判断osal_nv_item_init()返回成功才进行执行读写函数,程序中使用的NV item在 0x201-0x302之间,每一个item最多存储2个字节的数据,在研发阶段都没有发现什么问题,现在工程现场应用了一段时间,发现有些产品中这些数据被清除了,请帮忙分析一下原因。在客户应用中是否出现过这样的问题,我们在应用时还需要注意哪些问题,谢谢支持!

VV:

数据被清除,是指全部NV数据都没有吗?

还是说部分被改动了,部分还在。

Zhifeng Bai:

回复 VV:

从返回样机查看,NV中的数据都被清掉了,网络信息(信道和PanID)都发生了改变,从读取效果看,跟刚下完程序一个效果。

VV:

回复 Zhifeng Bai:

有没有可能中途出现过复位,然后在复位,启动以后start option有改动过了,导致重新擦除参数启动。

你们程序里面有没有改动这个start option的地方,另外你们的节点如果重新加网的话,会自动把之前保存的应用相关的参数擦除掉吗?

Zhifeng Bai:

回复 VV:

出现复位是有可能的,改动start option的地方也是有的,为了防止出现您说的这种情况,我们在程序中做了限制,start option需要配合和外部按键一起才能触发这种参数恢复默认值的操作,我们在应用的过程中对修改start option的操作做了记录,如果有类似的操作,只要不重新下载程序,都会有记录可查的,但从返回的问题样机根本看不出一点记录;另外节点如果重新加网的话,协调器中的参数也不会擦除掉。

VV:

回复 Zhifeng Bai:

如果有部分数据丢失的话,有可能是在运行过程中,在对部分数据进行读写的时候,导致出错。

如果数据全部都擦除的话,一定是软件的操作导致的。

你们现场协调器和节点都出现NV数据被擦除的情况吗?

Zhifeng Bai:

回复 VV:

我看到在协议栈中的main()函数里zgInit()函数之前有一个osal_nv_init()函数,能解释一下osal_nv_init()函数的工作过程吗?我这里出现数据丢失的问题现象都很一致,nv中的数据都被重置了,包括在zgInit()函数中没有进行过复位操作的几个NV Item,从现象上来看就是跟刚下完程序一个效果,所以我现在还是比较怀疑在zgInit()之外还有其他的地方出现了问题,请帮忙分析一下,谢谢支持!

Susan Yang:

回复 Zhifeng Bai:

您可以在IAR内追踪该函数,osal_nv_init 主要是调用了(void)initNV(); 

/********************************************************************* * @fn osal_nv_init * * @brief Initialize NV service. * * @param p – Not used. * * @return none */void osal_nv_init( void *p ){ (void)p; // Suppress Lint warning. (void)initNV(); // Always returns TRUE after pages have been erased.}

而(void)initNV(); 的定义可以在OSAL_Nv.c查找到

/********************************************************************* * @fn initNV * * @brief Initialize the NV flash pages. * * @param none * * @return TRUE */static uint8 initNV( void ){ osalNvPgHdr_t pgHdr; uint8 oldPg = OSAL_NV_PAGE_NULL; uint8 findDups = FALSE; uint8 pg;

pgRes = OSAL_NV_PAGE_NULL;

for ( pg = OSAL_NV_PAGE_BEG; pg <= OSAL_NV_PAGE_END; pg++ ) { HalFlashRead(pg, OSAL_NV_PAGE_HDR_OFFSET, (uint8 *)(&pgHdr), OSAL_NV_HDR_SIZE);

if ( pgHdr.active == OSAL_NV_ERASED_ID ) { if ( pgRes == OSAL_NV_PAGE_NULL ) { pgRes = pg; } else { setPageUse( pg, TRUE ); } } // An Xfer from this page was in progress. else if ( pgHdr.xfer != OSAL_NV_ERASED_ID ) { oldPg = pg; } }

// If a page compaction was interrupted before the old page was erased. if ( oldPg != OSAL_NV_PAGE_NULL ) { /* Interrupted compaction before the target of compaction was put in use; * so erase the target of compaction and start again. */ if ( pgRes != OSAL_NV_PAGE_NULL ) { erasePage( pgRes ); (void)compactPage( oldPg, OSAL_NV_ITEM_NULL ); } /* Interrupted compaction after the target of compaction was put in use, * but before the old page was erased; so erase it now and create a new reserve page. */ else { erasePage( oldPg ); pgRes = oldPg; } } else if ( pgRes != OSAL_NV_PAGE_NULL ) { erasePage( pgRes ); // The last page erase could have been interrupted by a power-cycle. } /* else if there is no reserve page, COMPACT_PAGE_CLEANUP() must have succeeded to put the old * reserve page (i.e. the target of the compacted items) into use but got interrupted by a reset * while trying to erase the page to be compacted. Such a page should only contain duplicate items * (i.e. all items will be marked 'Xfer') and thus should have the lost count equal to the page * size less the page header. */

for ( pg = OSAL_NV_PAGE_BEG; pg <= OSAL_NV_PAGE_END; pg++ ) { // Calculate page offset and lost bytes – any "old" item triggers an N^2 re-scan from start. if ( initPage( pg, OSAL_NV_ITEM_NULL, findDups ) != OSAL_NV_ITEM_NULL ) { findDups = TRUE; pg = (OSAL_NV_PAGE_BEG – 1); // Pre-decrement so that loop increment will start over at zero. continue; } }

if (findDups) { // Final pass to calculate page lost after invalidating duplicate items. for ( pg = OSAL_NV_PAGE_BEG; pg <= OSAL_NV_PAGE_END; pg++ ) { (void)initPage( pg, OSAL_NV_ITEM_NULL, FALSE ); } }

if ( pgRes == OSAL_NV_PAGE_NULL ) { uint8 idx, mostLost = 0;

for ( idx = 0; idx < OSAL_NV_PAGES_USED; idx++ ) { // Is this the page that was compacted? if (pgLost[idx] == (OSAL_NV_PAGE_SIZE – OSAL_NV_PAGE_HDR_SIZE)) { mostLost = idx; break; } /* This check is not expected to be necessary because the above test should always succeed * with an early loop exit. */ else if (pgLost[idx] > pgLost[mostLost]) { mostLost = idx; } }

pgRes = mostLost + OSAL_NV_PAGE_BEG; erasePage( pgRes ); // The last page erase had been interrupted by a power-cycle. }

return TRUE;}

赞(0)
未经允许不得转载:TI中文支持网 » CC2530内部flash数据丢失问题求教
分享到: 更多 (0)