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:如何将 CC2340R52 置于低功耗状态 (FreeRTOS):

Guru**** 2837190 points

Other Parts Discussed in Thread: SYSCONFIG, CC2340R5, LP-XDS110ET, LP-EM-CC2340R5, ENERGYTRACE

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

https://e2e.ti.com/support/wireless-connectivity/other-wireless-group/other-wireless/f/other-wireless-technologies-forum/1627449/cc2340r5-how-to-put-cc2340r52-into-low-power-state-freertos

器件型号: CC2340R5
Thread 中讨论的其他部件: Sysconfig、、 LP-XDS110ETENERGYTRACE

我目前正在处理一个使用 CC2340R52N0RGE 芯片的工程、在配置低功耗模式时遇到了一些问题:

1、SysConfig: FreeRTOS、 250kbps O-QPSK、PowerCC23X0_standbyPolicy、启用空闲挂钩功能  

2、在 main_freertos.c 中、定义的低功耗标志和低功耗唤醒信标:  

//-- =0: normal operation, =1: in low-power state
volatile uint8_t g_low_power_state = 0;

//-- Low-power wake-up semaphore
SemaphoreHandle_t g_wakeup_sem = NULL;

//-- Release semaphore
xSemaphoreGive(g_wakeup_sem); 

3、串行端口收到低功耗命令后:  

  设置。 g_low_power_state = 1
  当线程检测到g_low_power_state == 1时、它不会释放信号。
  然后、该线程将在以下位置阻塞:
  xResult = xSemaphoreTake(g_wakeup_sem, portMAX_DELAY);

4、通过按钮 (DIO6) 唤醒后、释放信标并且程序恢复运行。  

我可以清楚地看到,所有其他线程都被阻止,系统已进入空闲线程,但芯片的电流消耗保持在 10mA 左右。
 
请帮助检查阻止 CC2340R52 进入低功耗模式的不正确内容。
 
下面是我的程序架构和相关配置的屏幕截图。
 
P02.jpg
 
P03.jpg

 

P04.jpg

 

//========= main_freertos.c ===========
// lowpower indicate: =0, runing; =1, sleep
volatile uint8_t g_low_power_state = 0;
// wakeup semaphore
SemaphoreHandle_t g_wakeup_sem = NULL;


int main(){
    // create wakeup semaphore
    g_wakeup_sem = xSemaphoreCreateBinary();
    // lowpower indicate: =0, runing; =1, sleep
    g_low_power_state = 0;

    // creat 3 threads: 
    /*.......
    uart_thread
    rf_thread
    data_thread
    .................*/

    vTaskStartScheduler();  
    return 0;
}

//========= uart_thread.c ===========
void uart_thread(void *pvParameters){

    // -- some init functions
    BaseType_t xResult;

    while(1){
        xResult = xSemaphoreTake(g_wakeup_sem, portMAX_DELAY);
        
        if(xResult == pdTRUE && g_low_power_state == 0)
        {            
            // do something

            if( g_low_power_state == 0){
                xSemaphoreGive(g_wakeup_sem);
            }
                    
            vTaskDelay(pdMS_TO_TICKS(5));
        }
    }
}

//========= rf_thread.c ===========
void rf_thread(void *pvParameters){

    // -- some init functions
    BaseType_t xResult;

    while(1){
        xResult = xSemaphoreTake(g_wakeup_sem, portMAX_DELAY);
        
        if(xResult == pdTRUE && g_low_power_state == 0)
        {            
            // do something

            if( g_low_power_state == 0){
                xSemaphoreGive(g_wakeup_sem);
            }
                    
            vTaskDelay(pdMS_TO_TICKS(5));
        }
    }
}

//========= data_thread.c ===========
void data_thread(void *pvParameters){

    // -- some init functions
    BaseType_t xResult;

    while(1){
        xResult = xSemaphoreTake(g_wakeup_sem, portMAX_DELAY);
        
        if(xResult == pdTRUE && g_low_power_state == 0)
        {            
            // do something

            if( g_low_power_state == 0){
                xSemaphoreGive(g_wakeup_sem);
            }
                    
            vTaskDelay(pdMS_TO_TICKS(5));
        }
    }
}

//========= FreeRTOSConfig.h ===========
/* Idle hook function enabled or disabled */
#define configUSE_IDLE_HOOK 1



//========= ti_freertos_config.c ===========
/* Idle hook functions */
extern void dtk_power_idle(void);

void vApplicationIdleHook(void)
{
    dtk_power_idle();
}


//========= data_thread.c ===========
/* low power function */
void  dtk_power_idle(void)
{
   if(g_low_power_state ==1)
   {
      //board_led2_on();

      Power_idleFunc();

      //taskYIELD();
   }
      
}

/*  received lowPower command */
void lowPowerInsReceived(void)
{
    g_low_power_state =1;

}

/* press DIO6, out low power status*/
static void buttonCallback(uint_least8_t index)
{
   BaseType_t xHPW = pdFALSE;
   TickType_t now = xTaskGetTickCountFromISR();
   /* Debounce: ignore edges within 40ms */
   if ((now - sLastEdgeTick) < pdMS_TO_TICKS(40)) {
      return;
   }
   sLastEdgeTick = now;

   if( g_low_power_state == 1)
   {
       g_low_power_state =0;
       
       (void)xSemaphoreGiveFromISR(g_wakeup_sem, &xHPW);

       //-- restart 1MS timer --- //
       dtk1msTimerStart();
   }

   /* Active-low button with pull-up: 1=release, 0=press */
   uint32_t level = GPIO_read(CONFIG_GPIO_BUTTON_0_INPUT);
   if (level == 1) {
      /* Release detected: immediate single event */
      (void)xSemaphoreGiveFromISR(gBtnSingleSem, &xHPW);

      /* Start window on first click */
      if (sBtnClickCount == 0) {
         (void)xTimerChangePeriodFromISR(sBtnWindowTimer, pdMS_TO_TICKS(1200), &xHPW);
         (void)xTimerStartFromISR(sBtnWindowTimer, &xHPW);
      }
      sBtnClickCount++;
      /* Triple event once within window when reaching 3 or more */
      if (sBtnClickCount >= 3 && !sTripleEmitted) {
         (void)xSemaphoreGiveFromISR(gBtnTripleSem, &xHPW);
         sTripleEmitted = 1;
      }
      if (xHPW == pdTRUE) {
         portYIELD_FROM_ISR(xHPW);
      }
   }
}

 

最好的考虑。

宜化

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

    您好、Yicheng:

    您要测试哪种特定的低功耗状态?

    对于待机模式、器件通常会在可能的任何时候进入待机模式、否则、您可以通过使用 SLEEP 功能强制进入待机模式、前提是未禁用待机模式(以及阻止待机模式的外设未处于活动状态)。

    对于空闲模式、您可以首先使用 Power_setConstraint 函数禁用 STANDBY 模式、然后再次调用 SLEEP(或 ClockP 计时器)来测试此情况、请参阅下面的简单代码片段、其中我能够在空闲模式下测量 1.2mA、而<ClockP 0.7mA 表示待机模式。  

        while (1)
        {
            Power_setConstraint(PowerLPF3_DISALLOW_STANDBY); //disable standby so we can measure idle
            sleep(time);
            GPIO_toggle(CONFIG_GPIO_LED_0);
            Power_releaseConstraint(PowerLPF3_DISALLOW_STANDBY);
    
            sleep(time); //goto standby
            GPIO_toggle(CONFIG_GPIO_LED_0);
    
        }

    请记住分离 LED 跳线、因为这些跳线会显著增加电流消耗。  

    谢谢、
    Alex F

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

    您好 Alex、

    谢谢。

    我使用以下代码将 CC2340R52 置于低功耗状态,但未起作用 — 电流保持在 10mA 周围。

    //- at ti_freertos.c --//

    /*空闲挂钩函数*/
    extern void DTK_POWER_IDLE (void);

    void vApplicationIdleHook (void)

    DTK_POWER_IDLE();
    }

    //--在 data_thread.c --//处

    void DTK_POWER_IDLE (void)

    //Power_releaseDependency (PowerCC23X0_UART2);
    //Power_enableWakeupSource (CONFIG_GPIO_BUTTON_0_INPUT);// DIO6 唤醒
    //Power_enablePolicy ();

    while (1)

    if (g_low_power_state =1)

    //board_LED2_on ();

    ///Power_idleFunc ();
    //taskYIELD ();//

    power_setConstraint (PowerLPF3_disallow_standby);//禁用待机模式、以便我们可以测量空闲模式
    睡眠 (2);
    power_releaseConstraint (PowerLPF3_disallow_standby);
    睡眠 (2);//转到待机

    }
    }
    }

    我的预期要求是:当 CC2340R52 收到低功耗命令时、它进入低功耗状态、待机电流处于 1µA 级别。 该引脚应由 DIO6 的下拉电阻唤醒。

    您能否发布适用于 CC2340R52 的低功耗演示? 我在 simplelink_lowpower_f3_SDK_9_14_00_41 封装中找不到任何参考演示。

    最好的考虑。

    宜化

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

    您好、Yicheng:

    以下是禁用 STANDBY(待机)然后重新启用它的快速演示、器件将处于 STANDBY(待机)状态 1 秒、然后退出 STANDBY(空闲)状态 1 秒:

    e2e.ti.com/.../7433.empty_5F00_LP_5F00_EM_5F00_CC2340R5_5F00_freertos_5F00_ticlang.zip

    至于我们 SDK 中的“演示“、我建议查看驱动程序文件夹、因为它包含空工程(默认为待机/低功耗)和 gpioshutdown、应该会显示如何通过按钮关闭/唤醒器件。  

    路径应为:install location\ti\simplelink_lowpower_f3_SDK_9_14_00_41\examples\rtos\LP_EM_CC2340R5\drivers

    谢谢、
    Alex F

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

    您好 Alex

    我已按如下方式修改此项目:
    、时、LED 将闪烁 ON-OFF-ON、然后程序将在xResult = xSemaphoreTake(g_wakeup_sem, portMAX_DELAY);中阻止mainThread
    、后 2 μ s、程序自动进入空闲线程、此时进入低功耗状态。
    3 μ s、按按钮 1 触发唤醒。
    进入空闲后、我可以观察到电流消耗约为 0.5mA 的低功耗状态。 但是、我需要实现 1μA 级别 低功耗状态。 该工程将在上进行调试 LP-XDS110ET 仿真器和 LP-EM-CC2340R5 平台。 您能否请在开发板上运行该程序并检查需要进行哪些修改?
    最好的考虑。
    宜化
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Yicheng:

    我下载了您的附加工程并获得了以下 energytrace 结果(只需按下按钮 1)、它似乎与您的图像略有不同:

    从图像看,我可以看到两个 不同的功率级别是~0.2mA 和<0.7uA(待机);请注意,在测量待机时,我确实推荐功率分析仪,以获得最准确的测量结果。  

    您在图像中看到的各种细“脉冲“是充电峰值、是预期值。  

    我使用了 CC2340R5 LanchPad(修订版 B)、移除绿色和红色 LED 跳线。  

    谢谢、
    Alex F

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

    您好 Alex。

    非常感谢您反复回答我的问题。

    我想我可能发现了问题:  我的 Energy Trace 软件只能在 CCS 内进行调试时启动。可能由于调试模式、测量的电流似乎相对较高。

    我不知道如何使用 Energy Trace 作为 A 独立工具 。  我在 TI.com 上找不到相应的软件下载。  您能告诉我如何单独使用 Energytrace 吗?

    我有一个 LP-XDS110ET 。 我的 CCS 版本为: 20.4.0.13__1.10.0

    谢谢。

    宜化

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

    您好、Yicheng:

    CCS V20 使用 EnergyTrace 的方式与我们旧的 CCS 不同、这可能会引起一些混淆。  

    ]仅在 CCS
    内进行调试时才能启动我的 Energy Trace 软件

    您应该能够在调试模式之外运行 EnergyTrace、作为 CCS Eclipse 12.5 的示例、您只需启动 EnergyTrace 会话、只要需要进行测量、就可以直接运行 EnergyTrace 测量。 在这种情况下、您可以仅使用 CCS Eclipse 12.5 来进行 EnergyTrace 处理、否则使用 CCS v20 进行开发和刷写。 我知道、在我们的较旧 CCS v20 中、EnergyTrace 无法正常工作。   

    在上述响应中、我使用了 CCS Eclipse 12.5、在调试之外使用 EnergyTrace。  

    谢谢、
    Alex F

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好 Alex、
    再次感谢您耐心、彻底地回答我的问题。
    安装的模型 CCS v12.5 并获得了类似结果。
    测量结果表明这一点 CC2340R52 会在空闲状态下自动进入低功耗模式 、的电流消耗 1µA 级别
    再次感谢!
    宜化。