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.

SK-AM64: Using Watchdog Interrupt

Part Number: SK-AM64

We are currently using the MCU+ SDK for the AM64x eval board. We want to add a watchdog timer to our project. I've succefully run the watchdog interrupt example provided withing the MCU+ SDK (https://dev.ti.com/tirex/explore/node?node=ALTI8cer-dooM.8oNXSItw__rN4Qml4__LATEST) which is a NORTOS based example. But when I tried to use the same code for our RTOS based project it didn't work. I've used exactly the same code with the same sysconfig configurations for the WDT section. Is there any reason that the watchdog example does not work for the RTOS based project?? Any practical way to debug the watchdog timer from CCS IDE??

  • Hi,

    I tried adding watchdog to a freeRTOS project I am able to receive the interrupt.
    Please find the attached project and let me know if it works for you as well.
    empty_am64x-evm_r5fss0-0_freertos_ti-arm-clang.zip

    Regards

  • The attached project works fine, but when I try to use the same code for my project the interrupt is not received. The watchdog and all other drivers are successfully opened and all init functions work fine. The task where I initialize the HwIP object for the WDT also works without problem. Everything seems to be working, but I couldn't receive the interrupt. 

    Here is my linker file (I've changed this file to use the DDR instead of the SRAM):

    /* This is the stack that is used by code running within main()
     * In case of NORTOS,
     * - This means all the code outside of ISR uses this stack
     * In case of FreeRTOS
     * - This means all the code until vTaskStartScheduler() is called in main()
     *   uses this stack.
     * - After vTaskStartScheduler() each task created in FreeRTOS has its own stack
     */
    --stack_size=16384
    /* This is the heap size for malloc() API in NORTOS and FreeRTOS
     * This is also the heap used by pvPortMalloc in FreeRTOS
     */
    --heap_size=32768
    -e_vectors  /* This is the entry of the application, _vector MUST be plabed starting address 0x0 */
    
    /* This is the size of stack when R5 is in IRQ mode
     * In NORTOS,
     * - Here interrupt nesting is disabled as of now
     * - This is the stack used by ISRs registered as type IRQ
     * In FreeRTOS,
     * - Here interrupt nesting is enabled
     * - This is stack that is used initally when a IRQ is received
     * - But then the mode is switched to SVC mode and SVC stack is used for all user ISR callbacks
     * - Hence in FreeRTOS, IRQ stack size is less and SVC stack size is more
     */
    __IRQ_STACK_SIZE = 256;
    /* This is the size of stack when R5 is in IRQ mode
     * - In both NORTOS and FreeRTOS nesting is disabled for FIQ
     */
    __FIQ_STACK_SIZE = 256;
    __SVC_STACK_SIZE = 4096; /* This is the size of stack when R5 is in SVC mode */
    __ABORT_STACK_SIZE = 256;  /* This is the size of stack when R5 is in ABORT mode */
    __UNDEFINED_STACK_SIZE = 256;  /* This is the size of stack when R5 is in UNDEF mode */
    
    SECTIONS
    {
        /* This has the R5F entry point and vector table, this MUST be at 0x0 */
        .vectors:{} palign(8) > R5F_VECS
    
        /* This has the R5F boot code until MPU is enabled,  this MUST be at a address < 0x80000000
         * i.e this cannot be placed in DDR
         */
        GROUP {
            .text.hwi: palign(8)
            .text.cache: palign(8)
            .text.mpu: palign(8)
            .text.boot: palign(8)
            .text:abort: palign(8) /* this helps in loading symbols when using XIP mode */
        } > MSRAM
    
        /* This is rest of code. This can be placed in DDR if DDR is available and needed */
        GROUP {
            .text:   {} palign(8)   /* This is where code resides */
            .rodata: {} palign(8)   /* This is where const's go */
        } > DDR_1
    
        /* This is rest of initialized data. This can be placed in DDR if DDR is available and needed */
        GROUP {
            .data:   {} palign(8)   /* This is where initialized globals and static go */
        } > DDR_1 
    
        /* This is rest of uninitialized data. This can be placed in DDR if DDR is available and needed */
        GROUP {
            .bss:    {} palign(8)   /* This is where uninitialized globals go */
            RUN_START(__BSS_START)
            RUN_END(__BSS_END)
            .sysmem: {} palign(8)   /* This is where the malloc heap goes */
            .stack:  {} palign(8)   /* This is where the main() stack goes */
        } > DDR_1 
    
        /* This is where the stacks for different R5F modes go */
        GROUP {
            .irqstack: {. = . + __IRQ_STACK_SIZE;} align(8)
            RUN_START(__IRQ_STACK_START)
            RUN_END(__IRQ_STACK_END)
            .fiqstack: {. = . + __FIQ_STACK_SIZE;} align(8)
            RUN_START(__FIQ_STACK_START)
            RUN_END(__FIQ_STACK_END)
            .svcstack: {. = . + __SVC_STACK_SIZE;} align(8)
            RUN_START(__SVC_STACK_START)
            RUN_END(__SVC_STACK_END)
            .abortstack: {. = . + __ABORT_STACK_SIZE;} align(8)
            RUN_START(__ABORT_STACK_START)
            RUN_END(__ABORT_STACK_END)
            .undefinedstack: {. = . + __UNDEFINED_STACK_SIZE;} align(8)
            RUN_START(__UNDEFINED_STACK_START)
            RUN_END(__UNDEFINED_STACK_END)
        } > MSRAM
    
        /* Sections needed for C++ projects */
        GROUP {
            .ARM.exidx:  {} palign(8)   /* Needed for C++ exception handling */
            .init_array: {} palign(8)   /* Contains function pointers called before main */
            .fini_array: {} palign(8)   /* Contains function pointers called after main */
        } > MSRAM
    
        /* General purpose user shared memory, used in some examples */
        .bss.user_shared_mem (NOLOAD) : {} > USER_SHM_MEM
        /* this is used when Debug log's to shared memory are enabled, else this is not used */
        .bss.log_shared_mem  (NOLOAD) : {} > LOG_SHM_MEM
        /* this is used only when IPC RPMessage is enabled, else this is not used */
        .bss.ipc_vring_mem   (NOLOAD) : {} > RTOS_NORTOS_IPC_SHM_MEM
        /* General purpose non cacheable memory, used in some examples */
        .bss.nocache (NOLOAD) : {} > NON_CACHE_MEM
    }
    
    /*
    NOTE: Below memory is reserved for DMSC usage
     - During Boot till security handoff is complete
       0x701E0000 - 0x701FFFFF (128KB)
     - After "Security Handoff" is complete (i.e at run time)
       0x701F4000 - 0x701FFFFF (48KB)
    
     Security handoff is complete when this message is sent to the DMSC,
       TISCI_MSG_SEC_HANDOVER
    
     This should be sent once all cores are loaded and all application
     specific firewall calls are setup.
    */
    
    MEMORY
    {
        R5F_VECS  : ORIGIN = 0x00000000 , LENGTH = 0x00000040
        R5F_TCMA  : ORIGIN = 0x00000040 , LENGTH = 0x00007FC0
        R5F_TCMB0 : ORIGIN = 0x41010000 , LENGTH = 0x00008000
    
        /* memory segment used to hold CPU specific non-cached data, MAKE to add a MPU entry to mark this as non-cached */
        NON_CACHE_MEM : ORIGIN = 0x70060000 , LENGTH = 0x8000
    
        /* when using multi-core application's i.e more than one R5F/M4F active, make sure
         * this memory does not overlap with other R5F's
         */
        MSRAM     : ORIGIN = 0x70080000 , LENGTH = 0x40000
    
        /* This section can be used to put XIP section of the application in flash, make sure this does not overlap with
         * other CPUs. Also make sure to add a MPU entry for this section and mark it as cached and code executable
         */
        FLASH     : ORIGIN = 0x60100000 , LENGTH = 0x80000
    
    
            /* when using multi-core application's i.e more than one R5F/M4F active, make sure
         * this memory does not overlap with other R5F's
         */
        /* Resource table must be placed at the start of DDR_0 when R5 cores are early booting with Linux */
        DDR_0       : ORIGIN = 0xA0100000 , LENGTH = 0x1000
        DDR_1       : ORIGIN = 0xA0101000 , LENGTH = 0xEFF000
    
    
    
        /* shared memory segments */
        /* On R5F,
         * - make sure there is a MPU entry which maps below regions as non-cache
         */
        USER_SHM_MEM            : ORIGIN = 0x701D0000, LENGTH = 0x80
        LOG_SHM_MEM             : ORIGIN = 0x701D0000 + 0x80, LENGTH = 0x00004000 - 0x80
        RTOS_NORTOS_IPC_SHM_MEM : ORIGIN = 0x701D4000, LENGTH = 0x0000C000
    }
    

    And this is my project configuration generated using sysconfig tool:

    /**
     * These arguments were used when this file was generated. They will be automatically applied on subsequent loads
     * via the GUI or CLI. Run CLI with '--help' for additional information on how to override these arguments.
     * @cliArgs --device "AM64x_beta" --package "ALV" --part "Default" --context "r5fss0-0" --product "MCU_PLUS_SDK_AM64x@08.02.00"
     * @versions {"tool":"1.11.0+2225"}
     */
    
    /**
     * Import the modules used in this configuration.
     */
    const ipc        = scripting.addModule("/drivers/ipc/ipc");
    const uart       = scripting.addModule("/drivers/uart/uart", {}, false);
    const uart1      = uart.addInstance();
    const uart2      = uart.addInstance();
    const watchdog   = scripting.addModule("/drivers/watchdog/watchdog", {}, false);
    const watchdog1  = watchdog.addInstance();
    const debug_log  = scripting.addModule("/kernel/dpl/debug_log");
    const mpu_armv7  = scripting.addModule("/kernel/dpl/mpu_armv7", {}, false);
    const mpu_armv71 = mpu_armv7.addInstance();
    const mpu_armv72 = mpu_armv7.addInstance();
    const mpu_armv73 = mpu_armv7.addInstance();
    const mpu_armv74 = mpu_armv7.addInstance();
    const mpu_armv75 = mpu_armv7.addInstance();
    const mpu_armv76 = mpu_armv7.addInstance();
    const mpu_armv77 = mpu_armv7.addInstance();
    
    /**
     * Write custom configuration values to the imported modules.
     */
    ipc.r5fss1_0 = "NONE";
    ipc.r5fss1_1 = "NONE";
    ipc.m4fss0_0 = "NONE";
    
    uart1.$name        = "CONFIG_UART_1";
    uart1.intrEnable   = "USER_INTR";
    uart1.rxTrigLvl    = "1";
    uart1.UART.$assign = "USART0";
    
    uart2.$name        = "CONFIG_UART_2";
    uart2.UART.$assign = "USART5";
    
    watchdog1.$name          = "CONFIG_WDT0";
    watchdog1.instance       = "WDT8";
    watchdog1.expirationTime = 10000;
    watchdog1.resetMode      = "Watchdog_RESET_OFF";
    
    debug_log.enableUartLog            = true;
    debug_log.enableLogZoneInfo        = true;
    debug_log.enableMemLog             = true;
    debug_log.enableSharedMemLog       = true;
    debug_log.enableSharedMemLogReader = true;
    debug_log.uartLog.$name            = "CONFIG_UART0";
    
    mpu_armv71.$name             = "CONFIG_MPU_REGION0";
    mpu_armv71.size              = 31;
    mpu_armv71.attributes        = "Device";
    mpu_armv71.accessPermissions = "Supervisor RD+WR, User RD";
    mpu_armv71.allowExecute      = false;
    
    mpu_armv72.$name             = "CONFIG_MPU_REGION1";
    mpu_armv72.size              = 15;
    mpu_armv72.accessPermissions = "Supervisor RD+WR, User RD";
    
    mpu_armv73.$name             = "CONFIG_MPU_REGION2";
    mpu_armv73.baseAddr          = 0x41010000;
    mpu_armv73.size              = 15;
    mpu_armv73.accessPermissions = "Supervisor RD+WR, User RD";
    
    mpu_armv74.$name             = "CONFIG_MPU_REGION3";
    mpu_armv74.accessPermissions = "Supervisor RD+WR, User RD";
    mpu_armv74.baseAddr          = 0x70000000;
    mpu_armv74.size              = 21;
    
    mpu_armv75.$name        = "CONFIG_MPU_REGION4";
    mpu_armv75.baseAddr     = 0x701D0000;
    mpu_armv75.size         = 16;
    mpu_armv75.attributes   = "Device";
    mpu_armv75.allowExecute = false;
    
    mpu_armv76.$name             = "CONFIG_MPU_REGION5";
    mpu_armv76.baseAddr          = 0x60000000;
    mpu_armv76.size              = 28;
    mpu_armv76.accessPermissions = "Supervisor RD, User RD";
    
    mpu_armv77.$name    = "CONFIG_MPU_REGION6";
    mpu_armv77.baseAddr = 0x80000000;
    mpu_armv77.size     = 31;
    
    /**
     * Pinmux solution for unlocked pins/peripherals. This ensures that minor changes to the automatic solver in a future
     * version of the tool will not impact the pinmux you originally saw.  These lines can be completely deleted in order to
     * re-solve from scratch.
     */
    uart1.UART.RXD.$suggestSolution             = "ball.D15";
    uart1.UART.TXD.$suggestSolution             = "ball.C16";
    uart2.UART.RXD.$suggestSolution             = "ball.P16";
    uart2.UART.TXD.$suggestSolution             = "ball.R18";
    debug_log.uartLog.UART.$suggestSolution     = "USART1";
    debug_log.uartLog.UART.RXD.$suggestSolution = "ball.E15";
    debug_log.uartLog.UART.TXD.$suggestSolution = "ball.E14";
    

  • Edit: I've realized that the interrupt is actually received but after 16mn! Whatever expiration period I set from sysconfig, the interrupt is captured after this long period. Any reason for that?

  • Hi Fedi,

    So what I understand is that the watchdog demo works fine in no RTOS for you but when you add FREERTOS the interrupt is triggered after 16 min.
    Do you see the same behavior when you run the demo provided by me in the previous reply?

    I do not see anything wrong with your linker and sys config.
    If possible can you attach your project, that will help me in root causing the issue.

    Regards 

  • The NORTOS example works fine. The project you have attached works fine as well. When I use the same code of WDT in my project it doesn't work.

    I've tried to debug the problem using the ROV (Runtime Object View) and I've realized the following:

    - All the interrupt objects (mainly two uarts Num. 215 and Num. 210, and 1 WDT Num. 0) I'm using in my project are successfully created.

    - After 16mn, the hardware interrupt number 0, which is related to the watchdog is triggered.

    I can't understand why it takes so long for the interrupt to be triggered?

  • Hi Fedi,

    As I shared on my side I am not able to observe the issue.
    In order for me to comment or root cause this issue I will need your project.
    So if possible can you zip and share your project.

    Regards