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.

AM625: M4 MCU Only Deep Sleep mode

Part Number: AM625

Tool/software:

Hi,

I am using ipc_rpmsg_echo_linux (M4 and R5F firmware - mcu_plus_sdk_am62x_09_02_01_06) and I followed the commands in this link, I executed the following:

echo enabled > /sys/bus/platform/devices/5000000.m4fss/power/wakeup
echo mem > /sys/power/state



The MCU_UART was printing:

[IPC RPMSG ECHO] Suspend request to MCU-only mode received

[IPC RPMSG ECHO] Press a sinlge key on this terminal to resume the kernel from MCU only mode

Then, I recompiled the M4 firmware after adding the code below (next to 'Press a sinlge key on this terminal to resume the kernel from MCU only mode' in the code)

while(1)
{
    DebugP_log("loop here... \r\n");
}

When I put the device in MCU Only, I saw the 'loop here...' messages in the MCU debug uart. But, after the linux prints the messages below, the M4 firmware also stops printing the 'loop here' messages.

[ 22.658942] Freezing remaining freezable tasks completed (elapsed 0.001 seconds)
[ 22.666403] printk: Suspending console(s) (use no_console_suspend to debug)

Then, I tried to toggle an "MCU Domain Peripherals" GPIO. In normal operation, I saw the gpio toggling. But, when I put the device in MCU only, I did not see any toggling activity.

According to this sprad41.pdf the MCU should be supported.

Any idea why the M4 firmware behavior is different?

Thanks,

John

  • In  nutshell, our goal is to use MCU-only deep sleep mode to run a background task which is listed as a use-case for this mode.

    The developer portal states we only need to run two steps; but when we run these steps, the MCU stops executing once sleep is entered. Is there something else we should be doing to reach our goal of running a simple background task?

  • Hi John, Graham,

    Thanks for your question.

    Can you let us know if the MCU UART configuration is in interrupt or polled mode ?

    Looking forward to your response.

    Regards,

    Vaibhav

  • HI Vaibhav,

    I tried first interrupt - it didn't work. Then, I switched to polled mode and it didn't work as well.

    Regards,

    John

  • Hi John,

    Thanks for acknowledging the following.

    I tried first interrupt - it didn't work. Then, I switched to polled mode and it didn't work as well.

    I have few follow up questions to ask.

    So, once you ran the command: 

    echo mem > /sys/power/state

    Then after this did the logs like the following came?
    [  175.651151] PM: suspend entry (deep)
    [  175.655444] Filesystems sync: 0.000 seconds
    [  175.667559] Freezing user space processes
    [  175.673951] Freezing user space processes completed (elapsed 0.002 seconds)
    [  175.681105] OOM killer disabled.
    [  175.684404] Freezing remaining freezable tasks
    [  175.690155] Freezing remaining freezable tasks completed (elapsed 0.001 seconds)
    [  175.697574] printk: Suspending console(s) (use no_console_suspend to debug)
    [  175.722262] omap8250 2800000.serial: PM domain pd:146 will not be powered off
    [  175.954174] Disabling non-boot CPUs ...
    [  175.956374] psci: CPU1 killed (polled 0 ms)
    [  175.959326] psci: CPU2 killed (polled 0 ms)
    [  175.962024] psci: CPU3 killed (polled 4 ms)


    Also I would like to know if in the following code snippet:

    After which code (line number) you wrote the following piece of code?

    while(1)
    {
    DebugP_log("loop here... \r\n");
    }

    Regards,

    Vaibhav

  • HI Vaibhav,

    Yes, it shows the log messages:

    [  175.651151] PM: suspend entry (deep)
    [  175.655444] Filesystems sync: 0.000 seconds
    [  175.667559] Freezing user space processes
    [  175.673951] Freezing user space processes completed (elapsed 0.002 seconds)
    [  175.681105] OOM killer disabled.
    [  175.684404] Freezing remaining freezable tasks
    [  175.690155] Freezing remaining freezable tasks completed (elapsed 0.001 seconds)
    [  175.697574] printk: Suspending console(s) (use no_console_suspend to debug)
    [  175.722262] omap8250 2800000.serial: PM domain pd:146 will not be powered off
    [  175.954174] Disabling non-boot CPUs ...
    [  175.956374] psci: CPU1 killed (polled 0 ms)
    [  175.959326] psci: CPU2 killed (polled 0 ms)
    [  175.962024] psci: CPU3 killed (polled 4 ms)

    I put it in line 452

    while(1)
    {
    DebugP_log("loop here... \r\n");
    }

    Also, I tried disabling ipc_rpmsg_echo_main in m4fss0-0_freertos and put the loop.

    At this test, I do not care about how to wake up the device. I just want to see the m4 keeps running while in DS mode.

    Upon loading the m4 firmware, it started showing the 'client loop' in the uart.

     

    Then, I ran: echo mem > /sys/power/state

    It tried to go sleep but it bail out.

    The m4 didn't halt the printing of 'client loop'

    Then, I tried again issuing a command 'echo mem > /sys/power/state'

    My device successfully went to DS mode. But, the M4 also stopped printing 'client loop'.

    Regards,

    John

  • Hi Vaibhav,
    So we're able to service a watchdog with our M4 firmware. The firmware waits for a specific rpmsg and will the start toggling a GPIO (servicing a watchdog). Everything works fine in Linux, but when we put the device into MCU-only mode, the firmware stops executing.
    I saw this link software-dl.ti.com/.../DEVELOP_AND_DEBUG_DMR5.html and decided to try disabling LPM on the R5F.
    Under 'Disabling low power mode', I followed the 4 instructions:
    Update the line '-CONFIG_LPM_DM=y' in source/drivers/device_manager/rm_pm_hal/BuildConfigurationAM62X.mk to '-CONFIG_LPM_DM=n'.
    Remove the line '-DCONFIG_LPM_DM \' from source/drivers/device_manager/sciclient_direct/makefile.am62x.r5f.ti-arm-clang'.
    Remove the line '-DCONFIG_LPM_DM \' from source/drivers/device_manager/sciserver/makefile.am62x.r5f.ti-arm-clang.
    Remove the following lines from the linker file of the application that you are building.
    Rebuild
    When I do this, the M4 firmware continues to execute when issue the commands to enter MCU-only mode.
    I've attached a zip file with the modified MCU+ source code and modified rpmsg_char_simple source
    If you have an OS image that supports the IPC tests you should be able to:
    load the DM/MCU binaries onto the filesystem
    start the watchdog service with modified rpmsg_char_simple
    put the device into deep sleep
    With the firmware in place you just need to execute the rpmsg_char_simple command and then requrest MCU-only mode
    Modified rpmsg_char_simple command: rpmsg_char_simple -r 9 -o
    When you run this, main_gpio0_9 will toggle every 15 seconds
    Entering deep sleep:
    Note: when LPM is disabled, don't request the m4f as a wakeup source, results are inconsistent
    echo enabled > /sys/bus/platform/devices/5000000.m4fss/power/wakeup
    echo mem > /sys/power/state
    ------------------------------------------------------------------------------
    Results:
    LPM Enabled - WDT task runs until MCU-only is requested
    LPM Disabled - WDT Task runs even when MCU-only is requested. But we're not in a low power state.
    Now we just need to understand how to get MCU firmware to keep executing when LPM is enabled

    Regards

    John4810.patch.zip

  • Hi John,

    Thanks for you response.

    Please expect responses in few business days.

    Regards,

    Vaibhav

  • Hi John,

    I am actively working on this thread.

    You can expect follow up on this thread in sometime.

    Thank you very much for your patience.

    Regards,

    Vaibhav

  • Hello John,

    Graceful shutdown

    "It tried to go sleep but it bail out"

    code: timeout waiting for rproc completion... can't stop rproc -16

    This usually tells you that Linux is trying to shut down the remote core, so it sends the remote core a shutdown message and then waits for an ACK. If the remote core does not send an ACK, Linux refuses to shut down the core and aborts the low power mode transition.

    For more information about graceful shutdown and how it works, refer to the AM62x academy:
    https://dev.ti.com/tirex/explore/node?node=A__AXsPVjrUN0EAU1ezb.8iuQ__AM62-ACADEMY__uiYMDcq__LATEST 

    I suspect what is happening is that your edits disabled the M4F code that handles the low power mode transition. In
    examples/drivers/ipc/ipc_rpmsg_echo_linux/ipc_rpmsg_echo.c : 
    ipc_rp_mbox_callback
    lpm_mcu_uart_wakeup_task

    Let's back up 

    Let's start with the "known good" example. Does it work as expected?

    What happens if you run the unmodified code?

    After the MCU_UART outputs this:
    [IPC RPMSG ECHO] Suspend request to MCU-only mode received
    [IPC RPMSG ECHO] Press a sinlge key on this terminal to resume the kernel from MCU only mode

    Are you able to successfully wake up the processor by writing to the MCU_UART?

    Disabling low power mode in DM R5F is NOT what you want to do here 

    Disabling low power mode (LPM) would disable MCU-only low power mode as well.

    The only time you would care about this is if you were writing your own custom code to run on the DM R5F core, alongside the device management (DM) task. That does not matter if you are only developing on the M4F core.

    Regards,

    Nick

  • Hi Vaibhav,

    Thanks for the note. I was playing with the lpm driver and I found something very interesting. I restored the following files (putting back the 'CONFIG_LPM_DM')

    source/drivers/device_manager/rm_pm_hal/BuildConfigurationAM62X.mk
    source/drivers/device_manager/sciclient_direct/makefile.am62x.r5f.ti-arm-clang
    source/drivers/device_manager/sciserver/makefile.am62x.r5f.ti-arm-clang

    If I apply this patch

     

    diff --git a/mcu_plus_sdk_am62x_09_02_01_06/source/drivers/device_manager/sciclient_direct/sciclient_direct.c b/mcu_plus_sdk_am62x_09_02_01_06/source/drivers/device_manager/sciclient_direct/sciclient_direct.c
    index 34999d9..cb4a4d5 100644
    --- a/mcu_plus_sdk_am62x_09_02_01_06/source/drivers/device_manager/sciclient_direct/sciclient_direct.c
    +++ b/mcu_plus_sdk_am62x_09_02_01_06/source/drivers/device_manager/sciclient_direct/sciclient_direct.c
    @@ -667,7 +667,8 @@ int32_t Sciclient_ProcessPmMessage(const uint32_t reqFlags, void *tx_msg)
             case TISCI_MSG_LPM_WAKE_REASON               :
                 ret = dm_lpm_wake_reason_handler((uint32_t*)tx_msg); break;
             case TISCI_MSG_SET_IO_ISOLATION          :
    -            ret = dm_set_io_isolation_handler((uint32_t*)tx_msg); break;
    +            //ret = dm_set_io_isolation_handler((uint32_t*)tx_msg); break;
    +            ret = SUCCESS;
     #endif
    

    and run the commands below, my device went to DS mode, the power usage drops significantly - which is good and the thread/task that I implemented in M4 is running. Yes - It prints log messages in MCU_USART0  while in DS mode.

    echo enabled > /sys/bus/platform/devices/5000000.m4fss/power/wakeup
    echo mem > /sys/power/state

     

    NOTE: In the thread/task that I implemented, it toggles two gpios (GPIO6 - main domain gpio and MCU_GPIO0_7 - MCU domain gpio). In normal condition or non-DS mode I can scope the two gpios and it's doing the right thing (toggling high and low).

    void mcu_watchdog_ping(void *args)
    {
        while (gWdogTask == STATUS_WDOG_ENABLE)
        {
            uint64_t curTime = ClockP_getTimeUsec();
            DebugP_log("ping watchdog: %" PRId64 " usecs: gWatchdogBaseAddr %x" PRId32 "\r\n", curTime, gWatchdogBaseAddr);
            GPIO_pinWriteHigh(gWatchdogBaseAddr, gpinNum);
            GPIO_pinWriteHigh(gWatchdogBaseAddr1, gpinNum1); 
            ClockP_usleep(500);
            
            GPIO_pinWriteLow(gWatchdogBaseAddr, gpinNum);
            GPIO_pinWriteLow(gWatchdogBaseAddr1, gpinNum1);
            ClockP_usleep(500);
        }
    }

    Then, If the device is in DS mode (as I mentioned) my thread is now running, it toggles the two gpios. But, when I scope it, I did not see toggling (high or low). It looks like during the LPM, most of the IO's are disabled.

    Since, I have proven that a thread can be run (in a background) during a DS mode. Is it possible to access the 'main doman' GPIO6 and UART5 while the device is in DS mode?.

     

    Regards,

    John

     

  • Hi Nick,

    The original code works fine in MCU_ONLY. I did a quick hack to prove if the current implementation can run (continuously) a separate task/thread while the device is in MCU_ONLY DS mode.

    Please see my latest post, do you have any idea or workaround with regards to 'main domain' gpio and uart5 if possible to access it while the device is in DS mode.

    Regards,

    John

  • Hi John,

    The main domain is powered off in DS mode (and MCU-only mode too), so MCU cannot access main domain gpio and uart5. You can only use the mcu domain peripherals in MCU-only low power mode.

  • Hello John,

    Good to hear the original code is working as advertised. So the functionality probably works fine, and you just need to work through the design specifics (like in MCU only mode, the MCU power domain is clocked, while the MAIN power domain is not - thus, you can only use MCU domain peripherals).

    If you are still running into issues after you move to using MCU domain peripherals, please provide additional details (e.g., exactly which peripherals are being used, any error outputs, etc).

    Regards,

    Nick

  • Hi Nick,

    We are still waiting for the software support that run an application/thread in the background while the device is in MCU_ONLY/DS Mode. Then, I can test accessing MCU domain pheripherals.

    I know Vaibhav is working hard to help. I am curious maybe you have some idea that you can share for me to try?.

    Regards,

    John

  • Hello John,

    You do not need to define a "background task" in order to test the MCU peripherals.

    I would expect that during M4F initialization, you could just define your MCU_GPIO instance, and create the task that toggles the MCU_GPIO signal high and low. Assuming that your code doesn't hang somewhere (e.g., if your current code is trying to write to the main domain GPIO instance and hanging since the peripheral is no longer clocked), I would expect that task to continue running uninterrupted, even after the low power mode transition.

    As another note, the DDR is no longer clocked during this low power mode. So you need to make sure that you are not storing any of your associated variables & data in DDR that would be needed during low power mode.

    Regards,

    Nick

  • Hi Nick,

    The function that I posted 'mcu_watchdog_ping' is being executed by a task that I added in the code. What I was referring is that the task that I created was running continuously in non-DS mode or non MCU_ONLY. But, when I put the device in DS/MCU_ONLY, the said task stop running as well.

    You may try adding a task in the code and call this function.

    void test_test(void *args)
    {
        while(1)
        {
            DebugP_log("Hello\n\r");
            ClockP_usleep(500);
        }
    }

    Then, put the device in MCU_ONLY

    echo enabled > /sys/bus/platform/devices/5000000.m4fss/power/wakeup

    echo mem > /sys/power/state

    Then, you will notice it stop printing log messages as well. This is something that we need help to understand how to put the said task running while in DS mode.

    Regards,

    John

  • Or the simplest way is to add while loop in m4 main.c

    void freertos_main(void *args)
    {
        int32_t status = SystemP_SUCCESS;
    
        /* Open drivers */
        Drivers_open();
        /* Open flash and board drivers */
        status = Board_driversOpen();
        DebugP_assert(status==SystemP_SUCCESS);
    
        while(1)
        {
            DebugP_log("hello\r\n");
        }
    
        ipc_rpmsg_echo_main(NULL);
    
        /* Close board and flash drivers */
        Board_driversClose();
        /* Close drivers */
        Drivers_close();
    
        vTaskDelete(NULL);
    }

    Then, once you put it in DS mode you won't see any data in debug uart of the m4

  • Hello John,

    Can you please attach your example.syscfg file and test code for us to review? If you aren't comfortable posting that to the public forum, please send it to me in a direct message.

    Nick

  • Hello John,

    Thank you for your patience.

    I have been able to replicate this issue. I have attached the screenshot below.

    I see that the text "Testing MCU only mode !!" gets logged/printed only once, but it should continue to print as it is put under a infinite while loop.

    I am also attaching the section where I introduced the code for the while loop.

    Can you please confirm if my setup and log is mirroring yours ?

    Looking forward to your response.

    Regards,

    Vaibhav

  • Hello,

    We decided not to continue to implement it so I am closing this ticket.

    Regards,

    John