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.

AM6442: Redirect logs from core R5 to linux?

Part Number: AM6442

Hello 

I wonder if it is possible to redirect the logs from the firmware running on one of the R5 cores or PRU to the Linux system? Linux loads applications from /lib/firware onto the R5F0-0 core. The application uses the DebugP_log macro. Is it possible to view the logs somehow from Linux?

Thank's for response.

  • Hello Jakub,

    you should be able to see the output from DebugP_log via the Linux kernel's debugfs, e.g. at /sys/kernel/debug/remoteproc/remoteproc0/trace0

    Regards,

    Dominic

  • I see that in other examples, e.g. enet_lwip_cpsw_am64x-evm_r5fss0-0_freertos trace0 file with logs does not appear in any of the remoteprocX directories even though the example code contains DebugP_log () function calls. How to create this trace0 file?

  • Jakub,

    To confirm, are you able to see those logs with any of the methods listed here?

    https://software-dl.ti.com/mcu-plus-sdk/esd/AM64X/08_02_00_31/exports/docs/api_guide_am64x/KERNEL_DPL_DEBUG_PAGE.html

    Regards,

    Nick

  • Thank you for response.I have read this tutorial before. In sysconf I turned on the "Enable Memory Log" option. The following table has appeared in the generated ti_dpl_config.c file:

    char gDebugMemLog[DebugP_MEM_LOG_SIZE] __attribute__ ((section (".bss.debug_mem_trace_buf"), aligned (128)));
    uint32_t gDebugMemLogSize = DebugP_MEM_LOG_SIZE;

    But still does not work. I'm running enet_lwip_cpsw_am64x-evm_r5fss0-0_freertos example so after loading firmware by Linux trace file should be present in /sys/kernel/debug/remoteproc/remoteproc13/ but it is not. I also try command find . -name trace from /sys/kernel directory but with no results.

    Linker script:

    #include "ti_enet_config.h"
    
    /* 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=4096
    /* This is the heap size for malloc() API in NORTOS and FreeRTOS
     * This is also the heap used by pvPortMalloc in FreeRTOS
     */
    --heap_size=34000
    -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
    
        /* 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
    
        /* This is rest of uninitialized data. This can be placed in DDR if DDR is available and needed */
        GROUP {
            .sysmem: {} palign(8)   /* This is where the malloc heap goes */
            .stack:  {} palign(8)   /* This is where the main() stack goes */
        } > DDR
    
        GROUP {
            .bss:    {} palign(8)   /* This is where uninitialized globals go */
            RUN_START(__BSS_START)
            RUN_END(__BSS_END)
        } > DDR
    
        /* 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)
        } > DDR
    
        /* 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
    
        .enet_dma_mem {
            *(*ENET_DMA_DESC_MEMPOOL)
            *(*ENET_DMA_RING_MEMPOOL)
    #if (ENET_SYSCFG_PKT_POOL_ENABLE == 1)
            *(*ENET_DMA_PKT_MEMPOOL)
    #endif
        } (NOLOAD) {} ALIGN (128) > DDR
    
        .bss:ENET_DMA_OBJ_MEM (NOLOAD) {} ALIGN (128) > MSRAM
        .bss:ENET_DMA_PKT_INFO_MEMPOOL (NOLOAD) {} ALIGN (128) > MSRAM
        .bss:ENET_ICSSG_OCMC_MEM (NOLOAD) {} ALIGN (128) > MSRAM
    }
    
    /*
    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)
       0x701FC000 - 0x701FFFFF (16KB)
    
     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
    
        /* 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 = 0x140000
    
        /* 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 = 0x60200000 , LENGTH = 0x100000
    
        /* 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
         */
        DDR       : ORIGIN = 0x80000000 , LENGTH = 0x1000000
    
        /* 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 = 0x00004000
        LOG_SHM_MEM             : ORIGIN = 0x701D4000, LENGTH = 0x00004000
        RTOS_NORTOS_IPC_SHM_MEM : ORIGIN = 0x701D8000, LENGTH = 0x00008000
    }
    

  • Any suggestions what is wrong?

  • Hello Jakub,

    To confirm, remoteproc13 is actually the R5F you are looking at and not another core, right? the remoteproc number is not static, so it can theoretically change between boots. You can identify which core is associated with which remoteproc instance with the "name" attribute. For an example, see https://dev.ti.com/tirex/explore/node?a=7qm9DIS__LATEST&node=AGf47k0jnlMzDciz4huV1w__7qm9DIS__LATEST > Evaluating Linux > Booting Remote Cores from Linux.

    Another piece of information I just ran across is that Linux IPC must be enabled in the project settings in order for Linux to see the log in debugfs: https://software-dl.ti.com/mcu-plus-sdk/esd/AM64X/08_03_00_18/exports/docs/api_guide_am64x/IPC_GUIDE.html 

    Regards,

    Nick