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.

[参考译文] CC2541:CC2541在2.9小时内停止插件并恢复正常

Guru**** 2589265 points
Other Parts Discussed in Thread: CC2541, CC2590, CC2540

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

https://e2e.ti.com/support/wireless-connectivity/bluetooth-group/bluetooth/f/bluetooth-forum/716054/cc2541-cc2541-stop-to-avertise-for-2-9hours-and-back-to-normal

器件型号:CC2541
主题中讨论的其他器件: CC2590CC2540

您好!  

 我正在使用 CC2541和 CC2590开发 Beacon 模块。     

 开发环境为 BLESTACK 1.4.2.2 、使用 CC2541的 SimpleBLEBroadcaster -部分。  

当另一个相关的发动机完成 S/W 时 、运转正常。   但是、当我们使用超过50个组进行现场测试时、  几乎是100%的组

已停止2.9 小时的广播并恢复正常的广播条件。   每天发生一次或 每周随机发生一次。

  根据 E2E 建议、我尝试将 (#define HAL_SLEEP_ADJ_TICKs)时间从最初 的35调整为85、以确保足够的32MHz X tal

稳定时间。   但问题是持续发生的。   当我将节拍时间调整为15时、  问题始终发生。   

因此、我尝试排除 power_save 模式、如下所示仅用于测试。   然后、我发现32MHz X-Tal 在没有睡眠的情况下运行。    

 但问题  一再发生。     因此、我们认为这个问题不仅与 节拍时间有关。  

INT_HEPASS_LEN=2048
HALNODEBUG
OSAL_CBTIMER_NUM_TESS=1
HAL_AES_DMA=true
HAL_DMA=true
xPOWER_Saving
xPLUS_Broadcaster
xHAL_LCD=true
xHAL_LED=false
xHAL_key=true

我发现的另一个不祥现象是、当启用 power_save 模式时、该问题会引起32MHz X tal 振荡。    

因此、正常功耗0.8mA 在2.9小时内增加到8mA。 并在睡眠时恢复到0.8mA。   

为了避免 任何其他 未使用的 I/O 端口中断、  我在许多方面更改了端口设置。    但它不能解决问题。    

----------------------------------------------------

#if defined (CC2540_MINIDK)
 
 //注册所有关键事件-此应用程序将处理所有关键事件
 RegisterForKeys ( simpleBLEBroadcaster _taskID );
 
 //确保 LED 已关闭
 HalLedSet((HAL_LED_1| HAL_LED_2)、HAL_LED_MODE_OFF );
 
 //对于密钥卡板、将 GPIO 引脚设置为功耗优化状态
 //请注意、蜂鸣器仍然存在一些泄漏电流、
 //加速计、LED 和 PCB 上的按钮。
 
 P0SEL = 0;//将端口0配置为 GPIO
 P1SEL = 0;//将端口1配置为 GPIO
 P2SEL = 0;//将端口2配置为 GPIO

 P0DIR = 0xFC;//端口0引脚 P0.0和 P0.1作为输入(按钮)、
               //所有其他(P0.2-P0.7)作为输出
 P1DIR = 0xFF;//所有端口1引脚(P1.0-P1.7)作为输出
 P2DIR = 0x1F;//所有端口1引脚(P2.0-P2.4)作为输出
 
 P0 = 0x03;//端口0上的所有引脚均为低电平、P0.0和 P0.1除外(按钮)
 P1 = 0;  //端口1上的所有引脚均为低电平
 P2 = 0;  //端口2上的所有引脚均为低电平  
 
#endif //#if defined (CC2540_MINIDK)

------------------------------------------------------------------

您是否可以告知哪些 S/W 部件会导致此类问题?    以及如何解决?   

原理图如附件所示。   

 YS Kim

   

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

    您好!

    您能否在 OSAL.c 文件中的 void osal_run_system( void )下添加引脚切换?

    原始代码:

    执行{
    如果(taskEvents [idx])//任务是已就绪的最高优先级。
    {
    中断;
    }
    } while (++idx < taskCnt); 

    伪代码:

    执行{
    如果(taskEvents [idx])//任务是已就绪的最高优先级。
    {
    //if idx = 1、切换一次
    //如果 idx == 2、切换两次
    //……
    //...
    //...
    中断;
    }
    } while (++idx < taskCnt); 

    然后、当器件停止广播时、您能否连接逻辑分析仪以尽可能长地捕获引脚切换?

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

    尊敬的 Christin:

    感谢您的建议!

      

    我不是很熟悉 CC2541 BLE 堆栈。   但是、通过 插入 idx 计数切换例程、可以查找导致问题的任务事件。     

    在正常情况下  、它会将 切换计数增加到 Taskcnt。  

    由于我们不对多个项目使用逻辑分析仪、  因此我们现在没有它。   我们会尝试租赁它并检查您说的内容。       

    但问题发生的情况相当严重、  可能需要几天或一周以上的时间来检查。  

    在将设置测试环境并得出结果之前、   我想按 如下方式检查 Hal_SLEEP.c 备注中描述的某些内容。   

    注释中  有一条注释、即定时器2翻转可能会导致2.9小时的延迟。    
    由于我们将广告间隔设置为100ms、  因此我们可以使用频谱分析仪每100ms 看到一次射频辐射。      

    但是、当问题发生时、  从故障中恢复需要精确的2.9小时(2小时55分钟)。       

    因此、甚至 Max_sleep_Timeout 定义为40sec、 我们使用100msec 的广播间隔而无需连接、      

    任何可变参数设置都可能导致以下计时器过载情况?    
    是否有关键点?       

    对于临时解决方案、   如果广播时间超过1秒至1分钟、  我们可以嗅探它并重置计时器或

    重置任何内容以恢复广播?     如果可能、   您可以提供软件例程并告知插入位置吗?    

    我的应用程序在没有连接的情况下进行广播。     

    ------------------------------------------------------
    //允许的最大睡眠时间(以 ms 为单位)
    //注意:当 OSAL 计时器更新为32位时,对 halSleep 的调用是
    //      更改为采用32位 osal_timeout 值。 但自从 CC2540以来
    //      先前使用的16位 ll_McuPrecisionCount、halSleep 已修改
    //      也将 osal_timeout 限制为16位(请参阅 SVN 修订版27618)。
    //      但是,16位 LL_McuPrecisionCount 的最大值大约为41s,
    //      这比65.535s 的最大睡眠时间短! 因此这是有可能的
    //      在睡眠期间可能会发生 Timer2翻转,这可能会影响何时发生
    //      生成 OSAL 计时器事件。 OSAL 计时器软件应该是这样的
    //      进行更新以使用 Timer2的完整24位值、从而允许计时器
    //      事件最长为2.9小时,但直到可以正确完成为止
    //      最大睡眠持续时间将限制为小于 LL_McuPrecisionCount。
    //注意:BLE 不是问题,因为最大睡眠时间必须更短
    //      超过32s。
    #define MAX_SLEEP_TIMEOUT                  40000
    ------------------------------------------------------  

    YS Kim

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

    由于您说在禁用节能功能时问题仍然存在、因此问题不太可能出现睡眠定时器翻转。

    如果您可以提供我建议的逻辑分析仪跟踪、那将非常有用。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Christin:   

     在 逻辑分析仪准备好记录日志之前、  我们在正常情况下测量了与示波器的切换

    广播条件。    我们将切换计数插入  IDx + 1 、以同时识别任务事件[0] 。   输出端口为 P1_0。  

    由于广告停止条件不容易发生(需要几天或 2周以上)、   

    我们测量了在正常广告状态下切换的情况。    

     我们发现只有1个切换(Taskevent [0] )  以 100ms 的间隔进行处理。    

    当 我们添加了基于2分钟 计时器 的 UART TX 例程时、      发现了另外7次切换(任务事件[6])  

    和1次切换。    当我们通过触摸 X-Tal 引脚特意制造问题时 、广播是

    已停止。   但是 、7次切换  每2分钟发生一次、没有100ms 间隔1次切换(任务事件[0])。  

    即使在这种情况下、  如果通过2.9小时、 广播也会恢复正常。   

     ---------- simpleBLEBroadcaster 中的 UART 测试例程-------------------------------------------------------------

    静态空 performPeriodicTask( void )

       UINT8 CURRENT_ADV_ENABLE_STATUS;
       uint8 new_adv_enabled_status;
     
     new_adv_enabled_status = true;
       
       //查找当前的 GAP 广播状态
       GAPRole_GetParameter (GAPROLE_advertise_enabled,&current_adv_enabled_status);
       
       if (current_adv_enabled_status == false)
       {
          uart0Send (adv_status_off、sizeof (adv_status_off));
       }
       其他
       {
         uart0Send (adv_status_on、sizeof (adv_status_on));
       }
       
       //将 GAP 广播状态更改为与当前状态相反
       GAPRole_SetParameter( GAPROLE_advertise_enabled,sizeof ( uint8 ),&new_adv_enabled_status );
      

    --------------------------------------------------------------------

    上述高级状态检查例程始终未停止 。     但在何时不输出(adv_status_off)日志

    广播已停止。    始终输出(Adv_STATUS_ON)无纹波 实际 Adv_status。      

    供参考、 我添加了除 UART 代码之外的正常状态波形。        

    当然, 我们将继续使用 逻辑分析仪查找通告故障条件的切换状态。     

    但这可能需要2周以上、   我现在发布的是我发现的内容。    

    只需考虑 一下它可能会有所帮助、       因为我们 同时使用 CC2590 PA、  所以我们使用了 PA_EN 信号作为触发点。

        

               

     

     YS Kim

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

    如果我们检查您的硬件设计原理图和布局、您会介意吗? 这个问题有点奇怪、因为计时器绕回是用于睡眠计时器、当您禁用 PM 时、您不应该观察到相同的情况。(您仍然看到它...)
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Christin:   

     请参阅随附的 PCB 光绘文件。   

    由于我在之前的帖子中已经删除了文件、  因此我现在只发布与 PCB 相关的文件。

    U101为 CC2541、U102为 CC2590。    每个部件的1个引脚位于右上角位置。   Y101为32.768kHz RTC、Y102为

    32MHz X 直肠。   图层1的深绿色是连接到 GND 的铜平面。     由于我们参考的是 CC2541-CC2590参考设计、  

    原理图和 PCB 文件与 TI 参考设计几乎相同。         

    关于 当前正在进行的测试、  我们只关注 禁用的 Power_save 模式。    

    即使我们在几周前遇到2.9小时的高级停止故障情况、   当前测试也不会显示1周内的故障。  

    它由电流消耗日志和数字存储范围日志记录。    但是、正如我说过的、每两周可能会发生一次、  

    我们将在1周或2周后继续测试。   我不确定 为什么 power_save mode disabled test 显示 winthin 失败1天  

    我们几周前进行了测试。      更改后的代码仅是 UART 监控例程。   

      

    关于逻辑分析仪,   是否有 推荐的租赁模式 ?    

    根据我的调查、  在20MHz-32MHz 信号采集的情况下   、波形无法存储 在大存储 SSD 或中

    硬盘驱动器持续运行。    由于速度原因、应将其捕捉到逻辑分析仪内部的 RAM 中。   那么我们无法保存波形

    持续2-3周、直到出现故障。     如果我们通过插入多个'NOP'来延长切换持续时间、以确保所需时间的安全

    要将信号数据存储在 逻辑分析仪或 PC 的 SSD 或 HDD 中、  它可能是时序关键链路层或其他事件的一大障碍

    处理。             为了避免这种限制、 逻辑分析仪需要具有 可编程的触发器和捕获功能。    

    这是因为  我们需要在切换计数或模式 从正常切换更改时捕获波形。    

    正常 逻辑分析仪 每个通道只有边缘和电平触发器功能。     很难找到能够 对 TRGER 进行编程的模型

     在 所需 间隔内更改脉冲计数或模式时的条件。     

     

    YS Kim

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

    尊敬的 Christin:   

     2.9Hr 的故障 再次发生。      

     由于难以选择逻辑分析仪、  我们在120msec 内没有触发信号时使用条件捕获在1GHz 范围内捕获。        

    测试条件为禁用 POWER_SAVE 模式。       

    我所看到的,重要的因素是:

     在发生故障之前 、即使是 PA_EN 信号也会正常生成。  但   OSAL.c 中的 osal_run_system( void ) 未路由。  (如下所示无切换)。

     2.经过100ms 后  、生成了 PA_EN 信号。   软件再次进入  OSAL.c 中的 osal_run_system( void ) 。   (找到切换)

     3、广播停止、无 PA_EN、 2.9Hours 切换 。     然后恢复正常。        

    如果您在 下图中看到   、您会发现这一点。    但是 、由于示波器的存储限制、  我们无法放大在切换停止前发生的切换次数。

    我们已在手头购买了25kset 的 CC2541 /CC2590。  而5套套套套是在买方手中、  并受到 了旧买方的严重指责。   

    我非常期待您和 TI 工程师的关注、以解决这个问题。       如果需要、 我会将整个源代码转发给您以进行验证和修复。   

    然后、让我知道发送整个代码的电子邮件地址。    自从2个月前发生了这个问题,  这是紧急 的!!                 

    YS Kim

     

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

    是否可以实现看门狗并重置系统是否缺少一个 Adv 事件?(在每个 Adv 间隔结束时看门狗计时)

    我们的硬件团队已经检查了设计、看起来还可以。

    您的软件是否需要在定制硬件上运行?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Christin:   

     由于延迟很严重、   当 事件在1秒内未发生时、我已经执行了看门狗计时器复位例程。   

    发现系统运行正常、没有故障。       

    即使发生了转速狗重置、  也不应更改最初生成的随机地址、 我尝试放置该地址

    将数据传输到闪存存储器、如 OSAL.API 中所述。     但是  在看门狗复位发生后  、闪存内容变为0x00值。

    当然  、我插入 了条件斜升数种子、如  "if ((SLEEPSTA 和0x18)!= 0x10)"。

    但是,一旦生成看门狗复位, 当我在 main()的第一个函数调用中做一个断点时,闪存内容就会消失。    

    当然、通过使用 OSAL.API SNV 读取例程进行验证。   

    因此、我 将 Radom 地址保存在 RAM 中  、    并通过定义 glabal 变量使用了__no_init uint8随机性 addr[4]。    然后它就可以工作了。   

    但是    为什么在看门狗复位后 OSAL SNV 读数会导致'0x00'?    在 SimpleBLRBroadcaster .c 中、我已验证是否已打了手并读出正常   

    我在 读取后设置断点时的值。     

     下面是我使用多种方法测试的 SNV_READ/ WRITE 例程。   工作良好,但在 WDT 休息后消失了。   

    ///////////////////////////////////////////////////////////  

     WD_KICK ();
     if (成功!= osal_sv_read ((osalSnvId_t) sv_ID_app、(osalSnvlen_t) buf_len、advertData))
     
      {
       uint8故障= advertData[25];
     
       halIntState_t _s;
       HAL_ENTER_CRITICAL_SECTION (_s);    
       OSAL_SNV_WRITE ((osalSnvId_t) SNV_ID_APP、(osalSnvLen_t) buf_Len、advertData);
       HAL_EXIT_CRICAL_SECTION (_s);   

       uint16 waitx;  
       for (waitx =0;waitx < 60000;waitx++)
       {
         waitx = waitx;
       }
         
     
     if (成功!= osal_sv_read ((osalSnvId_t) sv_ID_app、(osalSnvlen_t) buf_len、advertData))
          {
         uint8失败= 0x44;     
          }  
         uint8 dd = advertData[25];
         uint8 cc = advertData[26];
      }
      //由 YSK Aug/19/'18 -WDT ctl 添加  
     }

        WD_KICK ();
        OSAL_SNV_read ((osalSnvId_t) SNV_ID_APP、(osalSnvLen_t) buf_Len、advertData);
    //  osal_sv_read ((osalSnvId_t) 0x80、(osalSnvlen_t) 0x4、pBuf);

    /////////////////////////////////////////////////////////////

    供参考、  

    我使用 Saleae 逻辑分析仪测量了恶意任务事件 、方法是通过触摸 RTC X-tal long time 特意进行 WD 复位。   

    您可以在网站上免费下载 Saleae 逻辑分析仪程序。     

    它看起来该 Web 不支持文件名"24MHz、720M 样本[7]6.logicdata"。     我无法上传。    

    YS Kim

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    在这种情况下、写入似乎不成功。

    您是否在应用程序中生成了随机地址? 您能给我发送您的完整信息吗? 我不关注你对这里的地址所说的话。

    您可以通过 e2e 消息框向我发送消息源。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    请参阅以下 随机编号播种 并将其写入 SNV 和 并从 SNV 读取。    

    有多 个调试用途线。    只是检查写作 和阅读是否正常。   

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    void SimpleBLEBroadcerter_Init( uint8 task_id )

    // 静态 uint8 ownAddress[B_ADDR_LEN];
     simpleBLEBroadcaster 任务 ID = task_id;
     
    #define buf_len 29
    #define SNV_ID_APP 0x80
     
    如果((SLEEPSTA 和0x18)!= 0x10) // 如果 WDT 未生成复位, 请按如下方式继续执行 ramdom number 种子例程。  
     {
     uint16 seed = Onboard rand ();
     advertData[25]=随机数[0]= HI_UINT16 (种子);//main_h
     advertData[26]=随机地址[1]= LO_UINT16 (种子);//main_l

     seed = Onboard rand();
     advertData[27]=随机地址[2]= HI_UINT16 (种子);//MINOR _h
     advertData[28]=随机地址[3]= LO_UINT16 (种子);//MINOR _l
     

                                    uint8 dd = advertData[25];
    断点此处--> uint8 cc = advertData[26];
          

       
     WD_KICK ();
     if (成功!= osal_sv_read ((osalSnvId_t) sv_ID_app、(osalSnvlen_t) buf_len、advertData))
     
      {
       uint8故障= advertData[25];
     
       halIntState_t _s;
       HAL_ENTER_CRITICAL_SECTION (_s);    
       OSAL_SNV_WRITE ((osalSnvId_t) SNV_ID_APP、(osalSnvLen_t) buf_Len、advertData);
       HAL_EXIT_CRICAL_SECTION (_s);   

       uint16 waitx;  
       for (waitx =0;waitx < 60000;waitx++)   //如果 SNV 写入需要时间则仅此函数。  
       {
         waitx = waitx;
       }
         
     
     if (成功!= osal_sv_read ((osalSnvId_t) sv_ID_app、(osalSnvlen_t) buf_len、advertData))
          {
         uint8失败= 0x44;     
          }  
         uint8 dd = advertData[25];
         uint8 cc = advertData[26];
      }
      //由 YSK Aug/19/'18 -WDT ctl 添加  
     }

        WD_KICK ();
        OSAL_SNV_read ((osalSnvId_t) SNV_ID_APP、(osalSnvLen_t) buf_Len、advertData);


                                   uint8 dd = advertData[25];
    断点此处--> uint8 cc = advertData[26];


    //。  已验证 advertData 写入和读取是否正常。   但不确定是否在上述例行程序的正确位置写入和读取。   
    不管怎样,当我读取、dd & cc 时, 它是原始生成的 ramdom 数据,作为上面设置的断点。   但在看门狗复位后 、它被读取为0x00。   
    因此、最终将 advertData[]替换为 non_init 随机addr[] 以快速解决问题。     


        advertData[25]=随机地址[0];  
        advertData[26]=随机地址[1];
        advertData[27]=随机地址[2];
        advertData[28]=随机地址[3];
     
     GAPRole_GetParameter (GAPROLE_BD_ADDR、BdAddress);

     随机地址[4];LL_ReadBDADDR (BdAddress);
     
     scanRspData[11]= BdAddress[5];
     scanRspData[12]= BdAddress[4];
     scanRspData[13]= BdAddress[3];
     scanRspData[14]=BdAddress[2];
     scanRspData[15]= BdAddress[1];
     scanRspData[16]= BdAddress[0];  

    //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    YS Kim

     

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

    在您的代码中、我建议您在执行写操作后回读并比较内容、然后再离开初始化阶段。

    此外、请确保在执行 SNV_WRITE 时获得成功返回值。

    请在 SNV_WRITE 之前和之后读回整个闪存映像、以便我们可以看到写入的内容。

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

      在 SNV 代码处理中的某个位置、我可能会出错。    

    由于我正在执行另一个紧急项目、而该项目通过取消初始化 RAM 来解决、  因此当我可以返回 CC2541时、我可能会更详细地进行研究。

     但与 MSP430或其他产品相比、8051内核相关的 CC2541文档似乎不够详细、缺少示例代码。   

    总之 ,感谢您的帮助!

    YS Kim