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.

LP-EM-CC2340R5: Does executing an additional task consume more power?

Part Number: LP-EM-CC2340R5
Other Parts Discussed in Thread: SYSCONFIG, CC2340R5

Tool/software:

Hi Ti team,
I followed the example to create a Task, but I've noticed that adding an extra Task increases power consumption. Is there a way to resolve this?

int main()
{
  /* Register Application callback to trap asserts raised in the Stack */
  halAssertCback = AssertHandler;
  RegisterAssertCback(AssertHandler);

  Board_init();

  /* Update User Configuration of the stack */
  user0Cfg.appServiceInfo->timerTickPeriod = ICall_getTickPeriod();
  user0Cfg.appServiceInfo->timerMaxMillisecond  = ICall_getMaxMSecs();

  /* Initialize all applications tasks */
  appMain();

  sub_proc();
  /* Start the FreeRTOS scheduler */
  vTaskStartScheduler();

  return 0;

}


void *emsThread(void *arg0)
{

    /* Configure the LED pin */
    GPIO_setConfig(CONFIG_GPIO_LED_0, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);
    GPIO_setConfig(CONFIG_GPIO_LED_1, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);

    /* Turn on user LED to indicate successful initialization */
    GPIO_write(CONFIG_GPIO_LED_0, CONFIG_GPIO_LED_OFF);
    GPIO_write(CONFIG_GPIO_LED_1, CONFIG_GPIO_LED_OFF);



    while(1)
    {
        if(connection_LED == 0)
        {
            if (sem_trywait(&sem) == 0)
            {
                UART2_write(uart, (char*)"device disconnect OK!\r\n", strlen((char*)"device disconnect OK!\r\n"), NULL);

            }

              GPIO_toggle(CONFIG_GPIO_LED_0);
              GPIO_write(CONFIG_GPIO_LED_1, CONFIG_GPIO_LED_OFF);
              //            UART2_write(uart, (char*)"Please connect device\r\n", strlen((char*)"Please connect device\r\n"), NULL);

              usleep(250000);

        }
        else
        {

            if (sem_trywait(&sem) == 0) { //receive to sem
                UART2_write(uart, (char*)"device connect OK!\r\n", strlen((char*)"device connect OK!\r\n"), NULL);
            }
            //GPIO_write(CONFIG_GPIO_LED_0, CONFIG_GPIO_LED_OFF);
            GPIO_write(CONFIG_GPIO_LED_1, CONFIG_GPIO_LED_ON);


            sleep(1);
        }


    }
}

void sub_proc(void)
{
    /* collect data Task. */
    pthread_t thread3;
    pthread_attr_t attrs3;
    struct sched_param priParam3;
    int retc;

    int32_t semStatus;

#if defined(Display_DISABLE_ALL)

    uint32_t status = UART2_STATUS_SUCCESS;
    const char echoPrompt[] = "Echoing characters:\r\n";

    /* Create a UART in CALLBACK read mode */
    UART2_Params_init(&uartParams);
    uartParams.readMode     = UART2_Mode_CALLBACK;
    uartParams.readCallback = callbackFxn;
    uartParams.baudRate     = 115200;

//    uart = UART2_open(CONFIG_UART2_0, &uartParams);

    if (uart == NULL)
    {
        /* UART2_open() failed */
        while (1) {}
    }
    UART2_read(uart, uartReadBuffer, UART_MAX_READ_SIZE, NULL);

    /* Turn on user LED to indicate successful initialization */
    //GPIO_write(CONFIG_GPIO_LED_0, CONFIG_GPIO_LED_ON);

    /* Pass NULL for bytesWritten since it's not used in this example */
    UART2_write(uart, echoPrompt, sizeof(echoPrompt), NULL);

#endif

    /* Create semaphore */
    semStatus = sem_init(&sem, 0, 0);

    if (semStatus != 0)
    {
        /* Error creating semaphore */
        while (1) {}
    }

    pthread_attr_init(&attrs3);


    /* Set priority, detach state, and stack size attributes */
    priParam3.sched_priority = 3;
    retc                    = pthread_attr_setschedparam(&attrs3, &priParam3);
    retc |= pthread_attr_setdetachstate(&attrs3, PTHREAD_CREATE_DETACHED);
    retc |= pthread_attr_setstacksize(&attrs3, THREADSTACKSIZE);
    if (retc != 0)
    {
        /* failed to set attributes */
        while (1) {}
    }

    retc = pthread_create(&thread3, &attrs3, emsThread, NULL);
    if (retc != 0)
    {
        /* pthread_create() failed */
        while (1) {}
    }

}



  • Hi,

    Having an additional task may increase power draw if the new tasks causes the device to be in active mode for longer than it would without the task or if it performs any power consuming actions (turning on LEDs or operating the peripherals).  However, just having an additional task should not by itself increase the power draw unless the actions the task takes consume more power. I would recommend looking at a graph of the current draw over time to see if the cause of the increase can be isolated.

    Best Regards,

    Jan

  • Hi Jan,

    Thank you for your suggestion, but how can I make the Task enter a power-saving state after completion? I've noticed that my Task remains active continuously.


    Regards,
    Anthony

  • Hi Anthony,

    Sleeping or yielding should allow another task to run and if no tasks need to run then the device should be placed in the lowest power state possibly (standby if no drivers are keeping the device awake). I see that you have a UART read operation. Is your UART being kept open at all times or are you closing it before going into standby?

    Best Regards,

    Jan

  • Hi jan,

    I apologize for my delayed response; I am currently on vacation until next Monday. Regarding the issue, I have tried turning off the UART and adding sleep to the task, but the power consumption remains unchanged. I can't think of any other ways to reduce it.

    //uart = UART2_open(CONFIG_UART2_0, &uartParams);
    //sleep(1);

    Regards,
    Anthony

  • Hi Anthony,

    No worries! Can you share what is the base example you are working off? Is this a BLE example? If so, then can you disable the display within the sysconfig settings? This is found inside the BLE module. Also, can you share how you are measuring the power draw? Could you share a picture of the setup? Enjoy your vacation! :)

    Best Regards,

    Jan

  • Hi jan,

    I'm doing some research based on basic_ble_LP_EM_CC2340R5_freertos_ticlang. I seem to have found my issue: I disabled the UART, but I didn't comment out the contents inside if (uart == NULL). After making this change, the power consumption has improved, but it still feels a bit high (original advertising consumption: 6μA; after adding Task: 120μA). I've already disabled the LED and UART and added sleep(). It seems that executing Tasks during broadcasting is not very suitable? Maybe I'm wrong. If you could provide some reference code, that would be great! Previously, when using the MSP430 MCU, it could enter low power mode and exit low power mode. I wonder if the CC2340R5 has similar features?





    Regards,
    Anthony

  • Hi Anthony,

    Agreed that the 120uA figure is very high if you are not intending to do anything in the separate task. Can you share the latest code of the separate task to make sure we haven't missed anything?

    The CC2340R5 uses the Power Manager to change the power state of the device during runtime. The Power Manager will automatically place the device in the lowest possible power state when all tasks have yielded. The lowest possible power state will depend on the peripherals being used at a given time. The following table from the datasheet details which power levels are achievable based on the peripherals that are active:

    Best Regards,

    Jan

  • Hi jan,

    My code hasn't changed much; I've only commented out the UART checks. The task runs independently, so the 120 uA power consumption seems reasonable. Where should I place the task that I need to run? Are there any relevant example codes I can refer to?

    int main()
    {
      /* Register Application callback to trap asserts raised in the Stack */
      halAssertCback = AssertHandler;
      RegisterAssertCback(AssertHandler);
    
      Board_init();
    
      /* Update User Configuration of the stack */
      user0Cfg.appServiceInfo->timerTickPeriod = ICall_getTickPeriod();
      user0Cfg.appServiceInfo->timerMaxMillisecond  = ICall_getMaxMSecs();
    
      /* Initialize all applications tasks */
      appMain();
    
      sub_proc();
      /* Start the FreeRTOS scheduler */
      vTaskStartScheduler();
    
      return 0;
    
    }


    void *emsThread(void *arg0)
    {
    
        /* Configure the LED pin */
        GPIO_setConfig(CONFIG_GPIO_LED_0, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);
        GPIO_setConfig(CONFIG_GPIO_LED_1, GPIO_CFG_OUT_STD | GPIO_CFG_OUT_LOW);
    
        /* Turn on user LED to indicate successful initialization */
        GPIO_write(CONFIG_GPIO_LED_0, CONFIG_GPIO_LED_OFF);
        GPIO_write(CONFIG_GPIO_LED_1, CONFIG_GPIO_LED_OFF);
    
    
    
        while(1)
        {
            if(connection_LED == 0)
            {
                if (sem_trywait(&sem) == 0)
                {
    //                UART2_write(uart, (char*)"device disconnect OK!\r\n", strlen((char*)"device disconnect OK!\r\n"), NULL);
    
                }
    
    //              GPIO_toggle(CONFIG_GPIO_LED_0);
    //              GPIO_write(CONFIG_GPIO_LED_1, CONFIG_GPIO_LED_OFF);
    
                  usleep(250000);
    
            }
            else
            {
    
                if (sem_trywait(&sem) == 0) { //receive to sem
    //                UART2_write(uart, (char*)"device connect OK!\r\n", strlen((char*)"device connect OK!\r\n"), NULL);
                }
                //GPIO_write(CONFIG_GPIO_LED_0, CONFIG_GPIO_LED_OFF);
    //            GPIO_write(CONFIG_GPIO_LED_1, CONFIG_GPIO_LED_ON);
    
    
                sleep(1);
            }
    
    
        }
    }



    void sub_proc(void)
    {
        /* collect data Task. */
        pthread_t thread3;
        pthread_attr_t attrs3;
        struct sched_param priParam3;
        int retc;
    
        int32_t semStatus;
    
    #if defined(Display_DISABLE_ALL)
    
        uint32_t status = UART2_STATUS_SUCCESS;
    
    
        /* Create a UART in CALLBACK read mode */
        UART2_Params_init(&uartParams);
        uartParams.readMode     = UART2_Mode_CALLBACK;
        uartParams.readCallback = callbackFxn;
        uartParams.baudRate     = 115200;
    
    //    uart = UART2_open(CONFIG_UART2_0, &uartParams);
    
    //    if (uart == NULL)
    //    {
            /* UART2_open() failed */
    //        while (1) {}
    //    }
    //    UART2_read(uart, uartReadBuffer, UART_MAX_READ_SIZE, NULL);
    
    
    #endif
    
        /* Create semaphore */
        semStatus = sem_init(&sem, 0, 0);
    
        if (semStatus != 0)
        {
            /* Error creating semaphore */
            while (1) {}
        }
    
        pthread_attr_init(&attrs3);
    
    
        /* Set priority, detach state, and stack size attributes */
        priParam3.sched_priority = 3;
        retc                    = pthread_attr_setschedparam(&attrs3, &priParam3);
        retc |= pthread_attr_setdetachstate(&attrs3, PTHREAD_CREATE_DETACHED);
        retc |= pthread_attr_setstacksize(&attrs3, THREADSTACKSIZE);
        if (retc != 0)
        {
            /* failed to set attributes */
            while (1) {}
        }
    
        retc = pthread_create(&thread3, &attrs3, emsThread, NULL);
        if (retc != 0)
        {
            /* pthread_create() failed */
            while (1) {}
        }
    
    }



    Regards,
    Anthony

  • Hi Anthony,

    I think the code you provided looks okay. If the task is running frequently then that may be the cause of the average current increase. A way to confirm would be to use a power analyzer and see the current over time graph.

    Best Regards,

    Jan

  • Hi Jan,

    I will reassess the overall architecture to achieve the goal of maximum energy efficiency. Thank you very much for your help.

    Regards,
    Anthony