你好!
有两个问题让我疑惑,项目设计也卡在这边,希望贵司能够提供一些技术支持,指点一下问题:
1. 我遇到一个非常奇怪的问题,这个问题我在贵司的论坛上看到过去年的时候有人问,可是一直没有被解答,
如下代码,
uint8 cali[4]={0x10,0x20,0x30,0x40};
uint8 cali_temp[4]={0x50,0x60,0x70,0x80};
uint8 m=0xce;
if(osal_snv_read(0x90,4,&cali_temp) == SUCCESS)
{
m=0x77;
}
else
{
m=0xaa;
}
单单只是执行snv_read的话,返回值总是NV_OPER_FAILED,而m的值为0xaa,也就是说读取snv失败了,可是如果我执行下面的代码,读取却成功了(即先write一次,再read):
if(osal_snv_write(0x90,4,cali) == SUCCESS)
{
…
}
else
{
…
}
if(osal_snv_read(0x90,4,cali_temp) == SUCCESS)
{
m=0x77;
}
else
{
m=0xaa;
}
cali_temp[]数组的值被赋予了{0x10,0x20,0x30,0x40}的值。
因为我们的设计需要存储一些数据,所以CPU每次reset都需要预先从snv读取一些数据,但是看起来读取操作出现错误了,而开机只能先读取保存的数据,请问这是怎么回事呢?
2. simpleBLECentral项目,本身他是只发送一个字节的,根据源程序,我稍微修改了一下,增加了第二个发送字节,用于在peripheral端检测接受的数据,如:
if ( simpleBLEDoWrite )
{
// Do a write
attWriteReq_t req;
req.handle = simpleBLECharHdl;
req.len = 2;
req.value[0] = simpleBLECharVal;
req.value[1] = 0x7c;
req.sig = 0;
req.cmd = 0;
status = GATT_WriteCharValue( simpleBLEConnHandle, &req, simpleBLETaskId );
}
else
{
// Do a read
attReadReq_t req;
req.handle = simpleBLECharHdl;
status = GATT_ReadCharValue( simpleBLEConnHandle, &req, simpleBLETaskId );
}
可是在调试的过程中发现,GATT_WriteCharValue无法发送数据,总是发送错误,LCD上提示"Write Error 13", 请问问题是出在哪里啊,TI协议栈能够支持多字节数据发送么?
Gang Zuo:
有TI工程师么?先顶起来!
Gang Zuo:
回复 Gang Zuo:
根据这个问题,我又仔细调试了下, 我用的是simpleBLEPeripheral工程,在SimpleBLEPeripheral_Main.c的Main()中已经有osal_snv_init()函数,当然,为了确保一点,我还是在我的osal_snv_read()前加了这个函数,可是发现还是无效。 /* Initialize NV system */ osal_snv_init(); /* Initialize LL */ /* Initialize the operating system */ osal_init_system(); 另外在调试的同时,发现peripheral.c中GAPRole_Init()函数也有调用osal_snv_read()函数,debug结果是读取的返回都是NV_OPER_FAILED, 也就是说其实所有的osal_snv_read()都fail了,经过深入的调试, // Restore Items from NV VOID osal_snv_read( BLE_NVID_IRK, KEYLEN, gapRole_IRK ); VOID osal_snv_read( BLE_NVID_CSRK, KEYLEN, gapRole_SRK ); VOID osal_snv_read( BLE_NVID_SIGNCOUNTER, sizeof( uint32 ), &gapRole_signCounter ); 我发现在单独掉用osal_snv_read时,语句 uint16 offset = findItem(activePg, pgOff, id);执行后,offset都是0,意味着所有返回都是NV_OPER_FAILED uint8 osal_snv_read( osalSnvId_t id, osalSnvLen_t len, void *pBuf ) { uint16 offset = findItem(activePg, pgOff, id); if (offset != 0) { HalFlashRead(activePg, offset, pBuf, len); return SUCCESS; } return NV_OPER_FAILED; } 然后我决定先write,再read,尝试看下这之间的不同,结果我发现…. 第一次调用osal_snv_write(),offset一样也是0,注意:此时pgoff值为4,所以osal_snv_write()能够返回SUCCESS是执行了蓝色代码,而后pgoff值变为12,之后再调用osal_snv_read()后offset就不为0了,值为4; uint8 osal_snv_write( osalSnvId_t id, osalSnvLen_t len, void *pBuf ) { uint16 alignedLen; { uint16 offset = findItem(activePg, pgOff, id); if (offset > 0) { uint8 tmp; osalSnvLen_t i; ….. ….. } alignedLen = ((len + OSAL_NV_WORD_SIZE – 1) / OSAL_NV_WORD_SIZE) * OSAL_NV_WORD_SIZE; if ( pgOff + alignedLen + OSAL_NV_WORD_SIZE > OSAL_NV_PAGE_SIZE ) { setXferPage(); compactPage(activePg); } // pBuf shall be referenced beyond its valid length to save code size. writeItem(activePg, pgOff, id, alignedLen, pBuf); if (failF) { return NV_OPER_FAILED; } pgOff += alignedLen + OSAL_NV_WORD_SIZE; return SUCCESS; } 所以我觉得关键还是在offset = findItem(activePg, pgOff, id);,不知道为什么返回都是0呢?
Gang Zuo:
根据这个问题,我又仔细调试了下, 我用的是simpleBLEPeripheral工程,在SimpleBLEPeripheral_Main.c的Main()中已经有osal_snv_init()函数,当然,为了确保一点,我还是在我的osal_snv_read()前加了这个函数,可是发现还是无效。 /* Initialize NV system */ osal_snv_init(); /* Initialize LL */ /* Initialize the operating system */ osal_init_system(); 另外在调试的同时,发现peripheral.c中GAPRole_Init()函数也有调用osal_snv_read()函数,debug结果是读取的返回都是NV_OPER_FAILED, 也就是说其实所有的osal_snv_read()都fail了,经过深入的调试, // Restore Items from NV VOID osal_snv_read( BLE_NVID_IRK, KEYLEN, gapRole_IRK ); VOID osal_snv_read( BLE_NVID_CSRK, KEYLEN, gapRole_SRK ); VOID osal_snv_read( BLE_NVID_SIGNCOUNTER, sizeof( uint32 ), &gapRole_signCounter ); 我发现在单独掉用osal_snv_read时,语句 uint16 offset = findItem(activePg, pgOff, id);执行后,offset都是0,意味着所有返回都是NV_OPER_FAILED uint8 osal_snv_read( osalSnvId_t id, osalSnvLen_t len, void *pBuf ) { uint16 offset = findItem(activePg, pgOff, id); if (offset != 0) { HalFlashRead(activePg, offset, pBuf, len); return SUCCESS; } return NV_OPER_FAILED; } 然后我决定先write,再read,尝试看下这之间的不同,结果我发现…. 第一次调用osal_snv_write(),offset一样也是0,注意:此时pgoff值为4,所以osal_snv_write()能够返回SUCCESS是执行了蓝色代码,而后pgoff值变为12,之后再调用osal_snv_read()后offset就不为0了,值为4; uint8 osal_snv_write( osalSnvId_t id, osalSnvLen_t len, void *pBuf ) { uint16 alignedLen; { uint16 offset = findItem(activePg, pgOff, id); if (offset > 0) { uint8 tmp; osalSnvLen_t i; ….. ….. } alignedLen = ((len + OSAL_NV_WORD_SIZE – 1) / OSAL_NV_WORD_SIZE) * OSAL_NV_WORD_SIZE; if ( pgOff + alignedLen + OSAL_NV_WORD_SIZE > OSAL_NV_PAGE_SIZE ) { setXferPage(); compactPage(activePg); } // pBuf shall be referenced beyond its valid length to save code size. writeItem(activePg, pgOff, id, alignedLen, pBuf); if (failF) { return NV_OPER_FAILED; } pgOff += alignedLen + OSAL_NV_WORD_SIZE; return SUCCESS; } 所以我觉得关键还是在offset = findItem(activePg, pgOff, id);,不知道为什么返回都是0呢?
ziliang xu:
1、NV也是一段存储区域,不是莫名其妙就有数据的,需要先写进去的;而且osal_snv_read此API明确的有说,不要试图去读取一段没有被写入过的区域,否则会导致返回NV_OPEN_FAILED.
2、GATT_WriteCharValue只能写一个characteristic值的前8位数据,你这种情况要使用GATT_WriteLongCharValue
yang zhi1:
回复 ziliang xu:
按照你的说法,这个就没意义了,每次要先写才能读还怎么保存数据,之前存的数据开机读一下就不行了
yang zhi1:
回复 Gang Zuo:
请问你解决了吗?我也是这个问题的
user4359466:
回复 yang zhi1:
一样的情况,如楼主有解决办法的话也希望能请教一下,万分感谢!共勉!
Gang Zuo:
回复 user4359466:
嗨,你好,你说的遇到的同样的情况是第一种写flash的问题还是第二条只能传一个字节的问题?
Yong Luo2:
回复 Gang Zuo:
请问这个问题是否已经解决了呢?我也是这样的情况,先写就可以读,先读失败的情况
Yong Luo2:
哦,知道了,因为调试的时候是重新烧录FLASH的,所以是未写状态,所以调试的时候会读取失败