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.

[参考译文] CC2340R5:ATT_Handle_Value_IND 事件在一段时间后停止发生

Guru**** 2350610 points
Other Parts Discussed in Thread: CC2340R5, CC2541
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/wireless-connectivity/bluetooth-group/bluetooth/f/bluetooth-forum/1414291/cc2340r5-att_handle_value_ind-event-stops-happening-after-some-time

器件型号:CC2340R5
Thread 中讨论的其他器件: CC2541

工具与软件:

你好

我´m 根据设置为 Central 的基本 BLE 工程(在 syscfg 文件中)开发一个应用、并´m 使用 simplelink_lowpower_f3_sdk_8_10_01_02中提供的示例。

以下实现已完成并按预期运行:

*连接处理-好

*服务发现-好的

*特征及其描述符发现-好的

* CCCD 发现-好的

*菜单模块选项和功能启用/禁用指示已创建-确定

*注册 BLEAPPUTIL_ATT_Handle_Value_IND 事件 -确定

我需要连接的外设有2个表示的特性集和1个设置为写入。 到目前为止、一切都运行得很好。

因此、在连接并发现上述所有特性后、我继续手动开启这两个特性之一的指示、结果是中央设备开始 按预期接收 ATT_Handle_Value_IND 通知。 我看到 Central 接收到的有效载荷数据是完美的。

起初、Central 仅接收第一个通知、而不接收第二个通知。 然后、我了解到中心需要在接收到指示数据后发回确认、因此我向函数 ATT_HandleValueCfm (gattMsg->connHandle)添加了一个调用;

完成此操作后、我的中心设备开始不断地接收指示、并且始终具有更新的数据。 但是、几秒钟后、指示事件 会停止、并且 ATT_FLOW_CTRL_COVERSE_EVENT 会发生。


这是访问通知数据并调用 ATT_HandleValueCfm 函数的事件代码片段。

    case   ATT_HANDLE_VALUE_IND:
        {
           
            MenuModule_printf(APP_MENU_PROFILE_STATUS_LINE1, 0, "Indication length= %d",
                                          gattMsg->msg.handleValueInd.len);
            MenuModule_printf(APP_MENU_PROFILE_STATUS_LINE2, 0, "DATA BYTES = 0x%02x, 0x%02x, 0x%02x",
                                          gattMsg->msg.handleValueInd.pValue[0],
                                          gattMsg->msg.handleValueInd.pValue[1],
                                          gattMsg->msg.handleValueInd.pValue[2]);
            pesoBruto=gattMsg->msg.handleValueInd.pValue[6]<<24;
            pesoBruto|=gattMsg->msg.handleValueInd.pValue[5]<<16;
            pesoBruto|=gattMsg->msg.handleValueInd.pValue[4]<<8;
            pesoBruto|=gattMsg->msg.handleValueInd.pValue[3];
            MenuModule_printf(APP_MENU_PROFILE_STATUS_LINE3, 0, "PESO BRUTO = %ld", pesoBruto);
            //ClockP_usleep(100000);
           // vTaskDelay( 1000 );
            ATT_HandleValueCfm(gattMsg->connHandle);

            break;
        }

我n´t 增加各种延迟、但我不知道这是否正确。 当我取消注释这两条延迟线(ClockP_usleep(10000);或 vTaskDelay(100 );)时,流控制违规不再发生,但指示事件仍会在几秒钟后停止。

下面是几个问题:

1) ATT_HandleValueCfm (gattMsg->connHandle)是否是确认指示的正确方法?

2) 2)如果是、这是否是调用它的正确位置? (在处理完有效载荷数据后的事件处理程序内部)

3)这些延迟在这个地方是一件好事?  (在处理完有效载荷数据后的事件处理程序内部)

提前感谢您

 

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    更多信息。 在上面发布的指示事件中、我添加了有关堆统计信息的打印信息。

    我看到总空闲大小开始正常、但每次指示处理后、该空闲大小会下降、直到剩余几个字节。 这是当一切停止工作(当然).

    我不n´t 分配任何类型的内存,因此我相信我不需要显式释放任何东西。

    下面是 指示停止前最后一个堆空闲大小值的示例。

        case   ATT_HANDLE_VALUE_IND:
            {
               
                MenuModule_printf(APP_MENU_PROFILE_STATUS_LINE1, 0, "Indication length= %d",
                                              gattMsg->msg.handleValueInd.len);
                
                ICall_heapStats_t stats;
                ICall_getHeapStats(&stats);
             
                MenuModule_printf(APP_MENU_PROFILE_STATUS_LINE2, 0, "Total Heap Size: %lu - Total Free Size: %lu",
                                              stats.totalSize,stats.totalFreeSize);
                pesoBruto=gattMsg->msg.handleValueInd.pValue[6]<<24;
                pesoBruto|=gattMsg->msg.handleValueInd.pValue[5]<<16;
                pesoBruto|=gattMsg->msg.handleValueInd.pValue[4]<<8;
                pesoBruto|=gattMsg->msg.handleValueInd.pValue[3];
                MenuModule_printf(APP_MENU_PROFILE_STATUS_LINE3, 0, "PESO BRUTO = %ld", pesoBruto);
                ClockP_usleep(10000);
               // vTaskDelay( 100 );
                ATT_HandleValueCfm(gattMsg->connHandle);
    
                break;
            }

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    在 GATT_eventhandler (Uint32 event、BLEAppUtil_msgHdr_t * pMsgData)函数末尾添加此行可解决上面的堆问题。

    GATT_BM_FREE (&(gattMsg->msg)、gattMsg->method);

    我想知道为什么在 SDK 原始 app_data.c 文件中默认没有它

    但 仍在发生 ATT_FLOW_CTRL_CONTROLLER_EVENT 问题。 我对这些延迟线的看法是错误的。 它们不会阻止此事件在中央应用程序中发生。 之前发生的情况是、在违反流控制之前、堆内存变得模糊了。 n´t 我停止了堆、那么无论使用何种延迟或者是否使用 μ s、都会发生这种违反。

    是否有人在思考如何防止中心人物这样做? ´m 我通过智能手机连接到外设来测试中央设备时、智能手机端从未发生过这种情况、因此我认为这可以在代码中的中央应用程序行为中解决。

    有什么想法吗?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!

    感谢您联系我们。 您能否分享一下您收到指示的速度有多快、以及每个指示中包含多少数据?

    此致、

    1月

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    你好 Jan

    外设设置为每80ms 指示一次。

    实际的有用数据量为15字节。 短封装。  

    谢谢你。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Alexandre、

    当中央设备/客户端违反 ATT 流控制要求时、ATT_FLOW_CTRL_COVERSE_EVENT 会发送到应用、例如:中央设备在发送指示确认之前发送读取请求。 除了可能违反流程或延迟将指示确认发送回外设的指示之外、您是否在其间执行其他一些操作?

    [quote userid="613683" url="~/support/wireless-connectivity/bluetooth-group/bluetooth/f/bluetooth-forum/1414291/cc2340r5-att_handle_value_ind-event-stops-happening-after-some-time 这样做后,我的中心开始不断地收到指示,总是有更新的数据。 但几秒钟后、指示事件 会停止、并会发生 ATT_FLOW_CTRL_DEVERSE_EVENT。

    您手头是否有蓝牙监听器? 比较您的中央设备和手机之间的音频日志可能有助于发现这里的差异。

    BR、

    David。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    你好、David

    感谢您花时间提供帮助。

    我没有进行任何可能触发 ATTRead 或任何其他 ATT 操作的修改。

    ´s 基本 BLE 项目已设为中央系统、并通过终端菜单进行操作、它通过串行端口提供、而我端所做的修改主要与 app_data.c、app_menu.c 和 app_connection.c 文件相关、但一切都由 LP_EM_CC2340R5侧按钮和终端菜单触发。 我´m 使用 LP_XDS110进行调试。

    n´t、我还没有任何 BT Sniffer。

    ´mn´t 此违规事件的含义、但我不确定触发它的原因、因为我没有特意启动可能导致此问题的任何 ATT 操作。

    外设有3个特征(2个表示、1个写入)、此时我只开启 char 1的指示、它是外设传输缓冲区、在这里每80ms 更新一次 μ´s 缓冲区、并打包15个字节的有效载荷数据通过指示发送到中央。

    我的代码不会写入任何其他特征、也不会尝试打开第二个特征中的指示。 此时、我只想接收数据缓冲区、处理信息并将其显示在某个位置。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    更新。 在某些情况下、我测量了接收到指示和外设发送某些指示之间的时间间隔为48ms、这很可能是因为它已经准备好数据并且接收到来自客户端的确认、然后就直接将其发送到了 BAT。

    我在外设侧´s 了这种行为、因为它也是我的、并且我可以完全控制它(使用 CC2541)。

    n´t 所需的80ms 原始间隔不是问题、而是我在示波器上没有看到的48ms 或更低的间隔。

    是否有办法调整堆栈以避免此问题? 可能导致此违规的指示之间的最短间隔时间是多少? 48ms 似乎不足以引起这一问题。

    它几乎感觉像是一个#define 某处是答案

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Alexandre、

    感谢您的更新、非常有用。 您能告诉我、您在代码中的哪个位置测量这个时间间隔吗? 可能会出现这样的情况:如您所述、中心站正在用排队消息回复。

    BR、

    David

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    你好、David

    再次感谢您联系我们。

    是在 ATT_Handle_Value_IND 事件内的函数 GATT_eventhandler (app_data.c)中。

    我´m 切换 LaunchPad 中的红色 LED 并使用示波器进行测量。

    case   ATT_HANDLE_VALUE_IND:
            {
                GPIO_toggle(CONFIG_GPIO_LED_RED);
                if(gattMsg->msg.handleValueInd.len==WT_PAYLOAD_SIZE)
                {
                  uint8_t* payload = gattMsg->msg.handleValueInd.pValue;
                  
                  batLevel  = payload[0];
                  unidade   = payload[1]&0x0F;
                  dpto      = payload[1]>>4;
                  pFlags    = payload[2];
                  
                  pesoBruto=payload[6]<<24;
                  pesoBruto|=payload[5]<<16;
                  pesoBruto|=payload[4]<<8;
                  pesoBruto|=payload[3];
    
                  pesoTara=payload[10]<<24;
                  pesoTara|=payload[9]<<16;
                  pesoTara|=payload[8]<<8;
                  pesoTara|=payload[7];
    
                  pesoLiq=payload[14]<<24;
                  pesoLiq|=payload[13]<<16;
                  pesoLiq|=payload[12]<<8;
                  pesoLiq|=payload[11];
                 
    #ifdef  USE_WEIGHT_HUD 
                  char *colorB, *colorT, *colorL;
                  int line = APP_MENU_PROFILE_STATUS_LINE1;
                  char format[100];
    #ifdef DEBUG_INDICATION 
                  line = APP_MENU_PROFILE_STATUS_LINE3;
    #endif         
                  //Mostra pesos
                  if(pFlags&FLAG_ERRO_AD)
                  {
                    MenuModule_printf(line++, 0, 
                                      MENU_MODULE_BORDER_COLOR_BLUE MENU_MODULE_COLOR_BOLD MENU_MODULE_COLOR_RED 
                                      "        REPORTADO ERRO AD       "
                                      MENU_MODULE_COLOR_RESET);
                  }
                  else if(pFlags&FLAG_OVER)
                  {
                     MenuModule_printf(line++, 0, 
                                      MENU_MODULE_BORDER_COLOR_BLUE MENU_MODULE_COLOR_BOLD MENU_MODULE_COLOR_RED 
                                      "           OVERLOAD!!!          "
                                      MENU_MODULE_COLOR_RESET);
                  }
                  else
                  {
                    if(pFlags&FLAG_BRUTO)
                    {
                      colorB=MENU_MODULE_COLOR_GREEN;
                      colorL=MENU_MODULE_COLOR_WHITE;
                    }
                    else
                    {
                      colorL=MENU_MODULE_COLOR_GREEN;
                      colorB=MENU_MODULE_COLOR_WHITE;
                    }
                    colorT=MENU_MODULE_COLOR_WHITE;
                    sprintf(format, "%s%sB: %%07ld %s%sT: %%07ld %s%sL: %%07ld",MENU_MODULE_BORDER_COLOR_BLUE,colorB,MENU_MODULE_BORDER_COLOR_BLUE,colorT,MENU_MODULE_BORDER_COLOR_BLUE,colorL);
                    MenuModule_printf(line++, 0,format, pesoBruto, pesoTara, pesoLiq);
                    //Mostra estabilidade
                    if(pFlags&FLAG_STABLE)
                    {
                      MenuModule_printf(line++, 0, 
                                        MENU_MODULE_BORDER_COLOR_BLUE MENU_MODULE_COLOR_BOLD MENU_MODULE_COLOR_GREEN 
                                        "             ESTAVEL            "
                                        MENU_MODULE_COLOR_RESET);
                    }
                    else
                    {
                      MenuModule_printf(line++, 0, 
                                        MENU_MODULE_BORDER_COLOR_BLUE MENU_MODULE_COLOR_BOLD MENU_MODULE_COLOR_YELLOW 
                                        "            INSTAVEL            "
                                        MENU_MODULE_COLOR_RESET);
                    }
                    //Mostra nível de bateria
                    if(batLevel<100)
                    {
                      if(batLevel>=60)
                        MenuModule_printf(line++, 0,MENU_MODULE_BORDER_COLOR_BLUE MENU_MODULE_COLOR_GREEN "          Bateria: %d " "%%         ",batLevel);
                      else if(batLevel>=30)
                        MenuModule_printf(line++, 0,MENU_MODULE_BORDER_COLOR_BLUE MENU_MODULE_COLOR_YELLOW "          Bateria: %d " "%%         ",batLevel);
                      else
                        MenuModule_printf(line++, 0,MENU_MODULE_BORDER_COLOR_BLUE MENU_MODULE_COLOR_RED "          Bateria: %d " "%%         ",batLevel);
                        
                    }
                    else
                    {
                      MenuModule_printf(line++, 0,MENU_MODULE_BORDER_COLOR_BLUE MENU_MODULE_COLOR_GREEN "         Bateria: %d " "%%         ",batLevel);
                    }
                    
                  }
    
    #endif
                }
                //ClockP_usleep(50000);
                //vTaskDelay( 80 );
                //Ack Indication
                ATT_HandleValueCfm(gattMsg->connHandle);
                break;
            }

    另一个有用的信息。 这似乎与外设发送指示的速度无关。  

    我修改了我的外设(CC2541、其代码基于 SimpleBLEPreipheral 工程)以发送指示的时间间隔超过100ms、但我仍然不时出现相同的问题。 这只需要更多的时间发生、但最终会发生。

    我还有一款使用 Laird BT900的产品、我在该产品中也实施了相同的 GATT 配置文件。 中央设备可以连接该产品并读取所有内容。 当我连接到 BT900并启用相同的字符指示时、不会出现此问题。 对于此产品、它运行时不会出现此违规问题。

    我知道 CC2541和 BT900的实现方式不同。 我只是想´m 到底发生了什么。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Alexandre、

    您是否已尝试使用另一个器件(如 CC23xx)作为外设来发送指示(我知道它适用于另一个外设)。 是否可以考虑使用 CC23xx 作为替代方案? 这当然不是事情目前无法正常工作的理由/解释、但我想知道这里是否有用于选择较新器件的窗口。 关于当前外设、您在使用适用于 CC2541的 SDK 版本?

    BR、

    David。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    你好、David

    n´t、我没有时间更改产品中的 BT 芯片。 这是一个´m 开发的新版本、我选择了 CC2340R5、因为它可以同时保持8个连接。 (CC2541只能保持3个)。

    如前所述、其中一种使用 Laird 的 BT900、另一种使用 CC2541。 我知道没有嗅探器、这变得很难修复、但我怀疑此流控违反问题是由 CC2541操作引起的。

    我确实延长了 CC2541 (外设)指示之间的时间间隔、这使得小提琴在很短的时间内停止了(它们彼此接近)。 当我将 CC2541外设远离中央设备时(来自外设的 RSSI 介于-80和-90 dBm 之间)、违反流控制的情况开始再次发生。

    对我的其他外围设备(BT900)执行同样的测试时、中心设备永远不会获得流量控制违规。 像处理 CC2541一样、我将 BT900放在远离中央的位置、但使用 BT900时、这个外设的流控从未发生过违反。 我可以尝试一下、 由于 LL_STATUS_ERROR_CONNECTION_TIMEOUT、连接会终止、因为外设超出范围。

    我一直在尝试在 CC2541固件端修改 SimpleBLEProject、以尝试纠正这种行为。 因此、现在人们的注意力从 CC2340R5转向了 CC2541、因为我确实认为问题出在那里。

    对此您有何看法? 我的意思是、为了避免这种情况、我可以尝试在 CC2541固件中设置、修改或启用什么?

    感谢您发送编修

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    OH、CC2541的 SDK 是 BLE-CC254x-1.5.2.1

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Alexandre、

    感谢您提供更多信息。 请让我在星期一之前仔细查看此问题并提供更好的建议。 我还将看到该 SDK 版本是否存在与流控制违规相关的已知问题。

    BR、

    David。