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.

RTOS/AM5728: Using interrupts on the IPU

Part Number: AM5728
Other Parts Discussed in Thread: SYSBIOS

Tool/software: TI-RTOS

I'm running Linux on the main Cortex A15 cores and using SYS/BIOS on IPU0 (Cortex-M4). I am wondering if it is possible to write my own custom code to handle interrupts on the IPU side and avoid having Linux handle them. For example, I might want my own custom UART driver (that is, not using the TI UART driver from the PDK) that has its own custom interrupt handling routines. My questions boil down to:

  1. How do I configure the processor and/or OS to ensure that only the IPU will handle certain interrupts?
  2. Are there any existing examples of how to do this?

  • The RTOS team have been notified. They will respond here.
  • Scott,

    We have created the following article that describes an example on SYSBIOS on IPU using GPIO when Linux is running on Cortex A15 using the examples provided here:
    processors.wiki.ti.com/.../Linux_IPC_on_AM57xx

    We have used PDK drivers in the example but you can do the same with your custom drivers.

    Hope this helps.

    Regards,
    Rahul

  • This doesn't really answer my question as all the details I'm interested in are hidden within SYSBIOS and PDK drivers .

    I'll ask it slightly differently:

    When then GPIO_LedBlink example sets up pin change interrupts, what are SYSBIOS and/or the GPIO driver doing in the background to ensure that Linux doesn't handle the interrupt instead of the IPU?

    Or is this a matter of configuring the Linux side of things to know not to handle the interrupt by modifying the kernel configuration and/or device tree?
  • Scott,

    Yes, if you plan to use a GPIO pin from the RTOS side of your code then it is responsibility of the System integrator to remove that pin from the Linux DTB files so that Linux doesn`t handle the interrupts corresponding to the GPIO pin. We have not automated this partitioning of resources between RTOS and Linux so it will need to be manually disabled in the DTB file that configures the kernel for the platform.

    Regards,
    Rahul
  • Thanks, Rahul. That helps a lot.
  • Scott,

    BAsed on this requirement, we have added instructions to create firmware for IPU using PDK UART LLD driver and IPC in RTOS and added it to the wiki article here:
    processors.wiki.ti.com/.../Linux_IPC_on_AM57xx

    Please review the steps and let us know if this works for you.

    Regards,
    Rahul
  • Rahul,

    Thanks for the example. I've been looking through this with my FAE and he's demonstrated that it works on the EVM. The problem I have with it is that it relies on a "UART STDIO" API that seems to be hard coded to use a specific UART. Thus if I want to use a different UART, it seems I have to rebuild the entire PDK and if I wanted to use two UARTs (e.g., using the RTOS UART driver without the stdio API) then I'm out of luck.

    Can you provide an example that uses ONLY the core UART driver API? E.g., read, write, open, close, etc. and NOT the STDIO API which seems to be tied to using only one UART through a convoluted stream of code?

  • Scott,

    After, you have created the PDK +IPC example project, it is fairly easy to eliminate the board library and use the UART driver directly to setup the UART standard IO operation

    Please comment out  following code :

    // boardCfg = BOARD_INIT_UART_STDIO;
    
    //  Board_init(boardCfg);

    and add the following code:

    #define UART_INSTANCE             2
    
    UART_stdioInit(UART_INSTANCE); // Add this call in place of Board_Init

    this call initializes the UART driver using the default parameters and sets it to 115.2 Kbps baud rate. 

    If you want to change the UART instance say to UART5 with your own configuration option:

    #define UART_INSTANCE = 4;
    
    // Perform PRCM  wake up for UART5 
    
    .........
    
    //Board_init(boardCfg); <- Only if you want to use board for pinmux setup.
    ...
    UART_socGetInitCfg(UART_INSTANCE, &uart_cfg);
    ...
    UART_socSetInitCfg(UART_INSTANCE, &uart_cfg);
    ...
    UART_stdioInit(UART_INSTANCE);
     
    //Application UART code here using UART_printf, UART_put, UART_scanf
    ...

    Note, the IPU code will require developers to set the pinmux in u-boot and to disconnect the UART5 instance in Linux using Device tree.

    Hope this helps.

    Regards,

    Rahul

  • Rahul,

    Thanks for the example code! That certainly makes working with the examples on other UARTs much less cumbersome than I had thought.

    I gave your suggestion a shot and changed the UART_INSTANCE to 4 so as to make use of UART5. I observed the following:

    If I boot up my system with a device tree that has the status of UART5 set to "okay" then I get he first string that the example prints, but subsequent strings are lost. If I instead boot with a device tree that sets UART5 to "disabled" then I get no output at all. We observed similar behavior when my FAE was on-site and we were working on a UART interface I developed. We suspect that the issue is that if we set UART5 to "okay" in the device tree that the kernel is setting up all the pins, clocks, and interrupts for us (thus we see one line but not other lines, because the kernel is taking over interrupts from the M4) and if we set the status to "disabled" that no such setup is being performed, thus we see no output from the UART.

    Thus it looks like my next step is to determine how to properly set up interrupts entirely from the M4 side of things.

  • Rahul,

    I wanted to let you know that I managed to get the example to work with both transmit and receive on UART 5. I have to disable UART5 from the Linux side (which we more or less knew) and, more importantly, I had to call a function to set up the crossbar on the M4 side properly. What I observed was that I couldn't just take an "open slot" in the crossbar table and assign the UART5 interrupt to it. It seems like it MUST be set to IRQ 24 (CSL_XBAR_INST_IPU1_IRQ_24 in my case) otherwise the driver doesn't handle the interrupts properly.

    I didn't see this documented anywhere and only figured this out by looking through the M4's NVIC vector table via CCS. Can you point me to any documentation or places in the code where I can look to see what the expected crossbar slots are for various peripherals? I plan on eventually setting up things like SPI and I2C on the M4 side so this would be helpful information to have available.


    Scott
  • Scott,

    The interrupt setup for UART instances are configured in UART_soc.c that is part of Processor SDK RTOS driver. If you look at the default setup then you will see that UART4 instance (UART5) on the device is set to use IRQ_24 in the UART_HwAttrs. the crossbar setup must use the IRQ or eventID (for DSP) that has been used on UART_HwAttr structure that is passed to the driver

    You will need to change this to use any other IRQ number that you wish to use. I have provided a snapshot of UART4 configuration in UART_soc.c

        {
    #ifdef _TMS320C6X
            CSL_DSP_UART4_REGS,
            OSAL_REGINT_INTVEC_EVENT_COMBINER,
    #elif defined(__ARM_ARCH_7A__)
            CSL_MPU_UART4_REGS,
            102,
    #else
            CSL_IPU_UART4_REGS,    // 
            24,  // IPU IRQ setting which needs to be used in XBAR setup 
    #endif
            34,  /* used only for C6x, reserved DSP1_IRQ_34 */
            CSL_UART_3_MODULE_FREQ,
            CSL_EDMA3_CHA_UART3_RX,
            CSL_EDMA3_CHA_UART3_TX,
            0,
            0,
            0,
            0,
            0,
            NULL,
            UART_RXTRIGLVL_8,
            UART_TXTRIGLVL_56,
            TRUE, /* default DMA mode */
            FALSE, /* Loopback disabled by default */
    		TRUE, /* Interrupt enabled by default */
        },

  • That makes sense now. Thanks, Rahul!