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.

How to setup a Hwi, can`t reach isr

Other Parts Discussed in Thread: AM3359, SYSBIOS

Hey,

I want to create a Hwi in my SYS/BIOS application. I tried it like this:

   Hwi_Params_init(&hwiParams);
   hwiParams.arg = 0;

   hwi1 = Hwi_create(67, isr_hwi1, &hwiParams, &eb); // id = 67 should be 1ms Timer

   if (NULL == hwi1)
   {
      System_printf("Hwi_create() failed!\n");
      BIOS_exit(0);
   }
   else
      System_printf("Hwi_create() successful!\n");

   Hwi_enableInterrupt(67); // optional

void isr_hwi1 ()
{
   i++;
//   System_printf("hwi running\n");
}

The problem is, that I don`t reach my isr. The interrupt should be generated from a timer module.

So, if I want to generate a interrupt and jump into an isr, must I configure the SoC- Module(Timer, ADC) and how do I do this?

I`m using SYS/BIOS6.33.03.33 with CCS 5.1 on AM3359

Thanks

  • Michael,

    There's a couple of things that need to be cleared up.

    1.  Typically Timers are supported by SYSBIOS and you would use the Timer module to create a Timer.  This would configure the Timer for you and setup the ISR.  For hardware that isn't supported by SYSBIOS then you would create a Hwi like you did above.  For this device the Timer module is:  ti.sysbios.timers.dmtimer.Timer.

    2.  The Timer that you have specified (id = 67) isn't currently supported in the lists of Timers for SYSBIOS.  The other DM Timers 2, 3, 4, 5, 6, 7 are supported.

    Judah

  • Michael,

    The DMTIMER_1ms timer is currently not supported by the SYS/BIOS ti.sysbios.timers.dmtimer.Timer module so you will have to configure the timer registers yourself to get it to generate the 1ms interrupt.

    However, DMTIMERs 2 thru 7 ARE managed by the ti.sysbios.timers.dmtimer.Timer module.

    So if all you need is a 1ms interrupt, try the following:

    add this to your config file:

    xdc.useModule('ti.sysbios.timers.dmtimer.Timer');

    and this to your C file:

    #include <ti/sysbios/timers/dmtimer/Timer.h>

    Timer_Handle timer;

    Timer_Params timerParams;

    Timer_Params_init(&timerParams);

    timerParams.period = 1000;

    timerParams.arg = 0;

    timer = Timer_create(Timer_ANY, isr_hwi1, &timerParams, &eb);

    This will grab an unused timer, configure it to generate an interrupt every 1ms, and bind your isr_hwi() function to that interrupt.

    If all you want is to have a function called every 1ms, you could simply create and add your own Clock object to the Clock module's service list. That way you can leverage off SYS/BIOS' internal clock tick timer interrupt:

    in your config file:

    xdc.useModule('ti.sysbios.knl.Clock');

    in your C file:

    #include <ti/sysbios/knl/Clock.h>

    Clock_Params clockParams;

    Clock_Handle clock;

    Clock_Params_init(&clockParams);

    clockParams.period = 1000;

    clockParams.arg = 0;

    clock = Clock_create(isr_hwi1, 1000, &clockParams, &eb);

    This will cause your isr_hwi1 function to be called every 1ms.

    One thing to keep in mind is that, as opposed to Hwi or Timer objects, Clock object functions are called within a Swi context.

    Alan

  • Alan,Judah,

    I would appreciate a response from you on a somewhat related query. I have two posts one on the multicore forum http://e2e.ti.com/support/dsp/c6000_multi-core_dsps/f/639/t/190112.aspx and one on the BIOS forum http://e2e.ti.com/support/embedded/bios/f/355/t/191282.aspx.

    Basically I am trying to setup an interrupt to occur every 10ms and then call a timer ISR in which i post a semaphore. In my main loop, I have an infinite while loop and a semaphore_pend within it on which the code is held till the interrupt goes off and the semaphore is posted. This way I can ensure each iteration of the loop is 10ms long and I can try and do all the processing I want in that 10ms period. The processing includes receiving packets from the PA and switch and I am finding some unwanted behaviour  in the ReceivePacket function which checks the Rx queue for a particular queue using the QMSS function. I have a few questions on BIOS vs CSL use of the interrupts and also how to go about making use of system_printf or something similiar and finally on this unwanted behaviour in ReceivePacket function.

    Your assistance would be greatly appreciated.

    Thanks, Aamir

  • 1) If you use CSL to set up an interrupt and bind it to an ISR function, that ISR function MUST NOT call any SYS/BIOS APIs (ie Semaphore_post()).

    Only interrupts created using a SYS/BIOS Hwi module can interact with SYS/BIOS.

    2) Calling System_printf() from an ISR function is usually a bad idea unless you have configured SysMin as your System.SupportProxy.

    Using SysStd will result in an Assert being hit when System_printf() is called from with a Hwi or Swi function.

    Alan

  • Alan,

    Thanks for your reply.

    1) Do you know the side effect if one was to call a SYSBIOS api within an ISR that is bound to an interrupt using the CSL? I did exactly that and though my timer is working based on me saving the TSCL count, I think it may be messing with the QM interrupt lines. Is there any example code that shows how to make use of the SYS/BIOS Hwi module to use as a starting point for my own desired application?

    2) I was not calling the System_printf from within an ISR function but rather in my main task which has a infinite while loop after the semaphore_pend where the code is waiting till the semaphore is posted in the ISR. The ISR just increments a count, posts a semahpore and clears the interrupt event using CSL_intcEventClear.

    Thanks, Aamir

  • You may never get another interrupt after calling Semaphore_pend() following a Semaphore_post() from your ISR because the interrupt was never properly "returned" from. Its hard to predict what all could happen.

    You can use CSL to configure a peripheral that generates an interrupt. But if you want to call BIOS APIs from within an interrupt handler associated with that peripheral the interrupt handler MUST be called by the SYS/BIOS interrupt dispatcher.

    Section 3.3 of the SYS/BIOS User's guide shows how to configure interrupts using a Hwi module:

         http://www.ti.com/lit/ug/spruex3k/spruex3k.pdf

    Alan

  • @Alan

    If I do what you have suggested this happens:

    [CortxA8] in handle: 0x0.
    Main stack base: 0x80015d40.
    Main stack size: 0x2000.
    R0 = 0x6000019f  R8  = 0x00000001
    R1 = 0x00000000  R9  = 0x0000003f
    R2 = 0x80014868  R10 = 0x00000002
    R3 = 0x80017b54  R11 = 0x0000003e
    R4 = 0x800119a8  R12 = 0x48042000
    R5 = 0x6000019f [CortxA8]  SP(R13) = 0x80017b68
    R6 = 0x8000b910  LR(R14) = 0x80008510
    R7 = 0x80014868  PC(R15) = 0x8000853c
    PSR = 0x6000019f
    ti.sys[CortxA8] bios.family.arm.exc.Exception: line 174: E_dataAbort: pc = 0x8000853c, lr = 0x80008510.
    xdc.runtime.Error.raise: terminating execution

    Do you have a solution for this?

    Is there a more detailed description of SYSBIOS than this datasheet, maybee with the APIs?

  • This exception occurs only with the timer. The Clock works.

  • The data abort exception appears to be due to a bus error occurring when the A8 tries to access the DMTimer3's registers (R12 is pointing to the base of the timer's registers at 0x48042000).

    This usually happens when the clocks necessary to access the timer registers have not been enabled.

    Have you enabled the clock to this timer? We use a GEL script (attached) for this purpose.

    Operationally you'll have to add your own startup code to enable the timers and other peripherals your application uses.

    Alan

    2148.AM335x_13x13_EVM.gel

  • Alan,

    Thanks for your post. I worked around the issue of calling the sysbios functions from within the ISR by making use of a global variable to perform the same functionality. Although I believe that the semaphore_post/pend are able to be called from my ISR without any side effect. I was able to get my timer working correctly with system_printf and a ISR being called every 10ms and returning control back to my main task. I was not setting up my EVM correctly after a system reset in the debug perspective. I needed to run the global default setup under scripts->evmc6678 init functions prior to running my application code.

    Aamir