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

CC2541 snv读写及simpleBLE数据发送的问题

你好!
有两个问题让我疑惑,项目设计也卡在这边,希望贵司能够提供一些技术支持,指点一下问题:

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的,所以是未写状态,所以调试的时候会读取失败

赞(0)
未经允许不得转载:TI中文支持网 » CC2541 snv读写及simpleBLE数据发送的问题
分享到: 更多 (0)