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.

SYS/BIOS and HWI problems on AM3359

Other Parts Discussed in Thread: AM3359, SYSBIOS

Hi,

     We are currently porting over our StarterWare project to SYS/BIOS and have most things running except for the hardware interrupts. The first we are trying is the EDMA completion interrupt. We replaced this sequence:

----------------------------------------------------------------------------------------------------------

    /* Registering EDMA3 Channel Controller 0 transfer completion interrupt.  */
    IntRegister(SYS_INT_EDMACOMPINT, Edma3ComplHandlerIsr);
    /* Setting the priority for EDMA3CC0 completion interrupt in AINTC. */
    IntPrioritySet(SYS_INT_EDMACOMPINT, 0, AINTC_HOSTINT_ROUTE_IRQ);
    /* Enabling the EDMA3CC0 completion interrupt in AINTC. */
    IntSystemEnable(SYS_INT_EDMACOMPINT);

----------------------------------------------------------------------------------------------------------

With this one:

void DMA_edma3_int_config(void)
{
Hwi_Params hwiParams_edma;
Hwi_FuncPtr  hwiFuncPointer = NULL;
Hwi_Handle tempHwiHandler_edma;

    hwiFuncPointer    = Edma3ComplHandlerIsr;
    Hwi_Params_init(&hwiParams_edma);

    // set the argument you want passed to your ISR function
    hwiParams_edma.arg        = 1;
    hwiParams_edma.priority    = 0;
    tempHwiHandler_edma    = Hwi_create(SYS_INT_EDMACOMPINT, hwiFuncPointer, &hwiParams_edma, NULL);
    if (tempHwiHandler_edma == NULL)
    {
        UARTprintf("Error installing EDMA interrupt, error code %d\n", tempHwiHandler_edma);
    }

    Hwi_enableInterrupt(SYS_INT_EDMACOMPINT);
}

     If we call DMA_edma3_int_config() before starting SYS/BIOS then soon after our main task is running the system will crash. When I say crash I mean lcd goes funky and all debug control is lost (No SYS/BIOS error codes either.) If we comment the DMA_edma3_int_config() call out, the main task runs fine. We never hit the ISR breakpoints so at first glance it seems just having a Hwi_create() call wigs out SYS/BIOS.

     Is there anything in the call that seems incorrect of do we need to set up some type of memory for the HWI (some special stack?)

Thanks for any help,

     John C.

  • I was reading some more and found this thread:

    http://e2e.ti.com/support/embedded/bios/f/355/p/268773/940617.aspx

          As soon as I changed the interrupt priority from 0 to 2, my EDMA interrupt started working correctly.  So on the AM3359 having an interrupt priority of zero is bad news. My initial guess is that is interfering with SYS/BIOS running. So this leads to my next question:

    1) What should the priorities be?

    2) If they are all the same, say 2, will this allow each to complete before the next is called or will a 2 preempt a 2 if the first interrupt has taken to long?

    Thanks,

         John C.

  • Hi John C.,

    I'm not familiar with EDMA but I can help with BIOS.

    John Conover said:
    2) If they are all the same, say 2, will this allow each to complete before the next is called or will a 2 preempt a 2 if the first interrupt has taken to long?

    If a Hwi ISR is currently running, and another Hwi occurs, I believe that it will preempt the currently running ISR.

    Please see the SYS/BIOS User's Guide, section "3.2.5 Yielding and Preemption." Figure 3.2 "Preemption Scenario" shows a nice example.

    Steve

  • Hey Steve,

         Section 3.3 states "All hardware interrupts run to completion. " Then the next paragraph says "If interrupts are globally enabled—that is, by calling Hwi_enable()—an ISR can be preempted by any interrupt that has been enabled". These paragraphs could be contradicting themselves depending on the definition "globally enabled". We have 9 Hardware interrupts that use the following code:

        // RTC interrupt
        hwiFuncPointer    = RTCIsr;
        Hwi_Params_init(&hwiParams_rtc);

        // set the argument you want passed to your ISR function
        hwiParams_rtc.arg        = 1;
        hwiParams_rtc.priority    = 2;
        tempHwiHandler_rtc = Hwi_create(SYS_INT_RTCINT ,hwiFuncPointer , &hwiParams_rtc, NULL);
        if (tempHwiHandler_rtc == NULL)
            UARTprintf("Error installing RTC interrupt, error code %d\n", tempHwiHandler_rtc);
        else
            Hwi_enableInterrupt(SYS_INT_RTCINT);

         So each interrupt calls Hwi_enableInterrupt(interrupt #). Is this considered "globally enabled?" 

    Thanks,

         John C.

  • Hi John C.,

    I spoke to a colleague of mine who better knows the rules of hardware interrupts.  What I said above is true for devices that do not support hardware interrupt priorities, but the device you are on (A8 I believe) does support this.

    John Conover said:
    Section 3.3 states "All hardware interrupts run to completion. " Then the next paragraph says "If interrupts are globally enabled—that is, by calling Hwi_enable()—an ISR can be preempted by any interrupt that has been enabled". These paragraphs could be contradicting themselves depending on the definition "globally enabled".

    I think what is meant by "run to completion" is that a Hwi thread is "non blocking."  Hwis can be preempted by other Hwis, but as I was saying, the rules that govern such preemption are hardware dependent.  Some h/w supports h/w interrupt priorites, and other h/w does not.

    On the A8, hardware interrupt priorities are supported, so this actually changes what I said in the previous post. In the case of when a Hwi that triggers that has equal priority to the currently running Hwi, it will not preempt that currently running Hwi with the same priority.

    However, if a Hwi of higher priority triggers, it will preempt the currently running Hwi.  Then, once that higher priority Hwi is finished running, context would switch back to lower pri Hwi.

    To take it even further, if both a higher priority Hwi and a Hwi of equal priority both triggered, the higher pri Hwi would preempt, then once finished, context would switch back to the originally running Hwi.  Once that ran to completion, the second (equal priority) Hwi would then get its turn to run.

    Steve

  • Hey Steve,

                Thanks for the information. My main concern with this is that we are about 75% through a port from StarterWare on the AM3359. None of the ISR's in StarterWare have code for insuring the stack values are saved if preempted by another interrupt as the ISRs run to completion. If the ISR's could be preempted then I would have to add additional code for register saves and restores which are currently not there (I also am not sure if there are any in SYS/BIOS.)

    Thanks again,

         John C.

  • Hi John C.

    From the SYS/BIOS user's guide, Table 3-1. Comparison of Thread Characteristics:

    Hwis: "Entire context minus saved-by callee registers (as defined by the TI C compiler) are saved to system."

    Fo

  • Steven,

                I guess my question would be what the TI compiler needs to determine that it is an ISR. I remember there being a special declaration needed on some Motorola processors to insure that the compiler would put in the extra code. Maybe something like this:

    void f () __attribute__ ((interrupt ("IRQ")));

    I'll look into this some more.

    Thanks,
    John C.
  • Hey Steven,

                    Tried using the keyword interrupt. The compiler like it but because SYS/BIOS ISR's want to pass in an argument, there is a conflict between the compiler's need to know and SYS/BIOS needing an argument.

    Original code:         void timer3Isr(UArg agr0)

    New cod:                 interrupt timer3Isr(UArg agr0)

    Error code:

    "../AIRTrac/timers.c", line 95: warning #169-D: argument of type "int (*)(UArg)" is incompatible with parameter of type "ti_sysbios_interfaces_ITimer_FuncPtr"
    "../AIRTrac/timers.c", line 130: warning #515-D: a value of type "int (*)(UArg)" cannot be assigned to an entity of type "ti_sysbios_family_arm_a8_intcps_Hwi_FuncPtr"
    >> Compilation failure
    "../AIRTrac/timers.c", line 185 (col. 11): error #832: interrupt declarations can only be applied to file scope functions returning void

         Do you think this is the right approach?

    Thanks,

         John C.

  • Hi John C.

    The format of your Hwi or Timer ISR function should match the prototype of for Hwi or Timer.  This is shown in the SYS/BIOS API document for Hwi and Timer modules:

    Void (*Hwi_FuncPtr)(UArg);

    Void (*Timer_FuncPtr)(UArg);

    So I think the problem you have here is that your function is defined to return an int, where it needs to be Void.

    Just to check ... have you configured your Hwi or Timer objects using the BIOS configuration file (*.cfg)?  Just want to make sure you're not stuck at that part or if you've already moved past your Hwi/Timer instance creation and are hitting compile problems with the ISR definitions.

    Steve

  • Hey Steve,

                       What I was trying to show in the last post is that the original code did use the standard API required by SYS/BIOS, but that I'm not sure that the compiler knows that it is indeed an interrupt, and should add the extra context saving code when it compiles it. When I try to use the standard "interrupt" keyword in the function definition, it no longer matches the SYS/BIOS API.

                        If you look a couple posts up you can see that I dynamically create the Hwi objects. There was mention in the SYS/BIOS manual about the deprecation of some C function calls that would do the equivalent  of using the interrupt key word in the function definition.

                        I guess my next question would be given the current API needed for SYS/BIOS ISR's, how do I get the compile to add the context saving code as interrup does not seem to work?

    Thanks,

         John C.

  • Hi John C.

    John Conover said:
    If you look a couple posts up you can see that I dynamically create the Hwi objects.

    Ok, I see that now.  My apologies, there are a lot of forums to answer, I sometimes forget the details in some of the threads :)

    I think the code above looks OK.  I don't think you need the interrupt keyword.  The interrupt manager should take care of the context switching for you (register saves to stack, etc.).

    John Conover said:
    [...] as interrup does not seem to work?

    Is your ISR never being reached?  Can you verify that the interrupt is enabled?

    Steve