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/SW-EK-TM4C129EXL: Hwi

In the below code, The myIsr5(), myIsr6(), myIdleFunc() doesn't work..
I am able to set breakpoints on all of the above function but the program flow doesn't go into these function,
the messages inside those functions are not printed on the console window.

/* XDCtools Header files */
#include<xdc/std.h>
#include<xdc/runtime/System.h>
#include<xdc/runtime/Error.h>
#include<xdc/sysbios/hal/Hwi.h>

/* TI-RTOS Header files */
#include<ti/sysbios/BIOS.h>
#include<ti/sysbios/knl/Task.h>
#include<ti/drivers/GPIO.h>

/* Board Header file */
#include "Board.h"

Bool Hwi5 = FALSE;
Bool Hwi6 = FALSE;

/* Runs when interrupt 5 occurs */
Void myIsr5(UArg arg) {
  if (arg == 10)
  {
    Hwi5 = TRUE;
    System_printf("In Hwi 5!!!!"); /* Able to set breakpoint here but the message is not printed in the console*/
   }
}

/* Runs when interrupt 6 occurs */
Void myIsr6(UArg arg) {
   if (arg == 12) {
     Hwi6 = TRUE
     System_printf("In Hwi 6!!!!"); /* Able to set breakpoint here but the message is not printed in the console*/
     }
}


/* The Idle thread checks for completion of interrupts 5 & 6 and exits when they have both completed. */
Void myIdleFunc()
{
   if (Hwi5&&Hwi6) {
     System_printf("Both interrupts have occurred!"); /* Able to set breakpoint here but the message is not printed in the console*/
     System_exit(0);
     }
}

int main(void)
 {
     /* Call board init functions */
     Board_initGeneral();
     Board_initGPIO();

     Hwi_Params hwiParams;
     Hwi_Handle myHwi;
     Hwi_Params_init(&hwiParams);

     /* Set myIsr6 parameters */
     hwiParams.arg = 12;
     hwiParams.enableInt = FALSE;
	 
     /* Create a Hwi object for interrupt number 6 that invokes myIsr6() with argument 12 */
     myHwi = Hwi_create(16, myIsr6, &hwiParams, NULL); 
     System_printf("Entering into Hwi"); /* Able to set breakpoint here but the message is not printed in the console*/
     if (myHwi == NULL) {
     System_abort("Hwi create failed");
     }

     Hwi_Params hwiParams_1;
     Hwi_Handle myHwi_1;
     Hwi_Params_init(&hwiParams_1);

     hwiParams_1.arg = 10;
     hwiParams_1.enableInt = FALSE;
     /* Create a Hwi object for interrupt number 18 that invokes myIsr5() with argument 10 */
     myHwi_1 = Hwi_create(18, myIsr5, &hwiParams_1, NULL);

     if (myHwi_1 == NULL) {
     System_abort("Hwi create failed"); /* Able to set breakpoint here but the message is not printed in the console*/
     }
	 
     Hwi_enableInterrupt(16);
     Hwi_enableInterrupt(18);
     System_printf("Entering into Hwi");
	 
     /* Turn on user LED */
     GPIO_write(Board_LED0, Board_LED_ON);
	 
     /* Start BIOS */
     BIOS_start();
     return (0);
 }

  • Hi,
    After the System_printf() you need to add System_flush() in order to print to the console.

    You are calling Hwi_create(16...) and Hwi_create(18...) and these are corresponding to the GPIOA and GPIOC. Are you using these two GPIO modules to generate the interrupts?
  • /*
     *  ======== empty_min.c ========
     */
    /* XDCtools Header files */
    #include <xdc/std.h>
    #include <xdc/std.h>
    #include <xdc/runtime/System.h>
    #include <xdc/runtime/Error.h>
    
    /* TI-RTOS Header files */
    #include <ti/sysbios/BIOS.h>
    #include <ti/sysbios/knl/Task.h>
    #include <ti/drivers/GPIO.h>
    #include <ti/sysbios/hal/Hwi.h>
    
    /* Board Header file */
    #include "Board.h"
    
    Bool Hwi5 = FALSE;
    Bool Hwi6 = FALSE;
    
    /* Runs when interrupt 39 occurs */
    
    Void myIsr5(UArg arg) {
     if (arg == 10)
     {
         Hwi5 = TRUE;
         //GPIO_toggle(Board_LED0);
         System_printf("passed!!!!");
         System_flush();
     }
    }
    
    /* Runs when interrupt 37 occurs */
    Void myIsr6(UArg arg) {
     if (arg == 12) {
         Hwi6 = TRUE;
         //GPIO_toggle(Board_LED0);
         System_printf("passed!!!!");
         System_flush();
     }
    }
    /* The Idle thread checks for completion of interrupts 5 & 6
     * and exits when they have both completed. */
    
    Void myIdleFunc()
    {
     if (Hwi5 && Hwi6) {
         System_printf("Both interrupts have occurred!");
         System_flush();
         System_exit(0);
     }
    }
    
    int main(void)
     {
         /* Call board init functions */
         Board_initGeneral();
         Board_initGPIO();
         Hwi_Params hwiParams;
         Hwi_Handle myHwi;
         Hwi_Params_init(&hwiParams);
         
    	 /* Set myIsr6 parameters */
         hwiParams.arg = 12;
         hwiParams.enableInt = FALSE;
        
         /* Create a Hwi object for interrupt number 6
         * that invokes myIsr6() with argument 12 */
         myHwi = Hwi_create(37, myIsr6, &hwiParams, NULL);
         System_printf("Entering into Hwi");
         System_flush();
         if (myHwi == NULL) {
         System_abort("Hwi create failed");
         System_flush();
         }
    
    
         Hwi_Params hwiParams_1;
         Hwi_Handle myHwi_1;
         Hwi_Params_init(&hwiParams_1);
    
         hwiParams_1.arg = 10;
         hwiParams_1.enableInt = FALSE;
          /* Create a Hwi object for interrupt number 16 that invokes myIsr6() with argument 12 */
         myHwi_1 = Hwi_create(39, myIsr5, &hwiParams_1, NULL);
    
         if (myHwi_1 == NULL) {
         System_abort("Hwi create failed");
         System_flush();
         }
    
         Hwi_enableInterrupt(37);
         Hwi_enableInterrupt(39);
         System_printf("\n Entering into Hwi");
         System_flush();
         /* Turn on user LED  */
         //GPIO_write(Board_LED0, Board_LED_ON);
         /* Start BIOS */
         BIOS_start();
         return (0);
     }
    

    Hi,

          I started calling  Hwi_create(37) and Hwi_create(39) and these are Timer interrupts and I was not able to print the messages inside the myIsr5()and myIsr6() functions.

          I had also added System_flush(); command to the code.  Code looks like....

  • Hi,

     I don't see in your code to configure the Timers. You only create the Hwi on vector 37 and 39. Even though these two vectors correspond to the Timer modules but they are not yet configured (i.e. setting up the period and enable the timeout interrupt and etc). Please take a look at the below example where Timer2 is used and the Hwi is created for vector number 39 which corresponds to the Timer2A. 

    //---------------------------------------------------------------------------------
    // Project: Blink TM4C BIOS Using Hwi (SOLUTION)
    // Author: Eric Wilbur
    // Date: June 2014
    //
    // Note: The function call TimerIntClear(TIMER2_BASE, TIMER_TIMA_TIMEOUT) HAS
    //       to be in the ISR. This fxn clears the TIMER's interrupt flag coming
    //       from the peripheral - it does NOT clear the CPU interrupt flag - that
    //       is done by hardware. The author struggled figuring this part out - hence
    //       the note. And, in the Swi lab, this fxn must be placed in the
    //       Timer_ISR fxn because it will be the new ISR.
    //
    // Follow these steps to create this project in CCSv6.0:
    // 1. Project -> New CCS Project
    // 2. Select Template:
    //    - TI-RTOS for Tiva-C -> Driver Examples -> EK-TM4C123 LP -> Example Projects ->
    //      Empty Project
    //    - Empty Project contains full instrumentation (UIA, RTOS Analyzer) and
    //      paths set up for the TI-RTOS version of MSP430Ware
    // 3. Delete the following files:
    //    - Board.h, empty.c, EK_TM4C123GXL.c/h, empty_readme.txt
    // 4. Add main.c from TI-RTOS Workshop Solution file for this lab
    // 5. Edit empty.cfg as needed (to add/subtract) BIOS services, delete given Task
    // 6. Build, load, run...
    //----------------------------------------------------------------------------------
    
    
    //----------------------------------------
    // BIOS header files
    //----------------------------------------
    #include <xdc/std.h>  						//mandatory - have to include first, for BIOS types
    #include <ti/sysbios/BIOS.h> 				//mandatory - if you call APIs like BIOS_start()
    #include <xdc/runtime/Log.h>				//needed for any Log_info() call
    #include <xdc/cfg/global.h> 				//header file for statically defined objects/handles
    #include <xdc/runtime/System.h>
    #include <xdc/runtime/Error.h>
    #include <ti/sysbios/hal/Hwi.h>
    
    
    //------------------------------------------
    // TivaWare Header Files
    //------------------------------------------
    #include <stdint.h>
    #include <stdbool.h>
    
    #include "inc/hw_types.h"
    #include "inc/hw_memmap.h"
    #include "driverlib/sysctl.h"
    #include "driverlib/gpio.h"
    #include "inc/hw_ints.h"
    #include "driverlib/interrupt.h"
    #include "driverlib/timer.h"
    
    
    //----------------------------------------
    // Prototypes
    //----------------------------------------
    void hardware_init(void);
    void ledToggle(void);
    
    
    //---------------------------------------
    // Globals
    //---------------------------------------
    volatile int16_t i16ToggleCount = 0;
    
    
    //---------------------------------------------------------------------------
    // main()
    //---------------------------------------------------------------------------
    void main(void)
    {
    
        hardware_init();                         // init hardware via Xware
    
        Hwi_Params hwiParams;
        Hwi_Handle myHwi;
        Error_Block eb;
        /* Initialize error block and hwiParams to default values */
        Error_init(&eb);
        Hwi_Params_init(&hwiParams);
        hwiParams.enableInt = FALSE;
        myHwi = Hwi_create(39, (Hwi_FuncPtr)ledToggle, &hwiParams, &eb);
        if (myHwi == NULL) {
        System_abort("Hwi create failed");
        }
        Hwi_enableInterrupt(39);
    
    
       BIOS_start();
    
    }
    
    
    //---------------------------------------------------------------------------
    // hardware_init()
    //
    // inits GPIO pins for toggling the LED
    //---------------------------------------------------------------------------
    void hardware_init(void)
    {
    	uint32_t ui32Period;
    
    	//Set CPU Clock to 40MHz. 400MHz PLL/2 = 200 DIV 5 = 40MHz
    	SysCtlClockSet(SYSCTL_SYSDIV_5|SYSCTL_USE_PLL|SYSCTL_XTAL_16MHZ|SYSCTL_OSC_MAIN);
    
    	// ADD Tiva-C GPIO setup - enables port, sets pins 1-3 (RGB) pins for output
    	SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);
    	GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3);
    
    	// Turn on the LED
    	GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3, 4);
    
    	// Timer 2 setup code
    	SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER2);			// enable Timer 2 periph clks
    	TimerConfigure(TIMER2_BASE, TIMER_CFG_PERIODIC);		// cfg Timer 2 mode - periodic
    
    	ui32Period = (SysCtlClockGet() /2);						// period = CPU clk div 2 (500ms)
    	TimerLoadSet(TIMER2_BASE, TIMER_A, ui32Period);			// set Timer 2 period
    
    	TimerIntEnable(TIMER2_BASE, TIMER_TIMA_TIMEOUT);		// enables Timer 2 to interrupt CPU
    
    	TimerEnable(TIMER2_BASE, TIMER_A);						// enable Timer 2
    
    }
    
    
    //---------------------------------------------------------------------------
    // ledToggle()
    //
    // toggles LED on Tiva-C LaunchPad
    //---------------------------------------------------------------------------
    void ledToggle(void)
    {
        TimerIntClear(TIMER2_BASE, TIMER_TIMA_TIMEOUT);			// must clear timer flag FROM timer
    
    	// LED values - 2=RED, 4=BLUE, 8=GREEN
    	if(GPIOPinRead(GPIO_PORTF_BASE, GPIO_PIN_2))
    	{
    		GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3, 0);
    	}
    	else
    	{
    		GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_2, 4);
    	}
    
    	i16ToggleCount += 1;									// keep track of #toggles
    
    	Log_info1("LED TOGGLED [%u] TIMES",i16ToggleCount);		// send toggle count to UIA
    
    }
    
    

  • Hi Tsai,

              I have edited the code and the code is as follows. As of my understanding the code should operate the Hwi's and then the Idle function but the Idle function doesn't seem to be running. The code and the output of the code in console window can be as follows,

    /* XDCtools Header files */
    #include <xdc/std.h>
    #include <xdc/std.h>
    #include <xdc/runtime/System.h>
    #include <xdc/runtime/Error.h>
    #include <ti/sysbios/hal/Hwi.h>
    
    /* BIOS Header files */
    #include <ti/sysbios/BIOS.h>
    #include <ti/sysbios/knl/Task.h>
    
    /* TI-RTOS Header files */
    
    #include <ti/drivers/GPIO.h>
    
    /* Board Header file */
    #include "Board.h"
    
    /* Tivaware Header file */
    #include "inc/hw_types.h"
    #include "inc/hw_memmap.h"
    #include "driverlib/sysctl.h"
    #include "driverlib/gpio.h"
    #include "inc/hw_ints.h"
    #include "driverlib/interrupt.h"
    #include "driverlib/timer.h"
    
    #include <stdint.h>
    #include <stdbool.h>
    
    Bool Hwi5 = FALSE;
    
    
    void hardware_init(void);
    void ledToggle(void);
    
    
    void myIsr5(UArg arg) {
    	TimerIntClear(TIMER2_BASE, TIMER_TIMA_TIMEOUT); // must clear timer flag from timer
    	if (arg == 10)
    	{
    	    Hwi5 = TRUE;
    	    System_printf("\n passed!!!!");
    	    System_flush();
    	}
    }
    
    void myIdleFunc()
    {
    	if (Hwi5) 
    	{
    	    System_printf("Idle part of the code!");
    	    System_flush();
    	    System_exit(0);
    	}
    }
    
    void hardware_init()
    {
    
         uint32_t ui32Period;
    
         //Set CPU Clock to 40MHz. 400MHz PLL/2 = 200 DIV 5 = 40MHz
         SysCtlClockSet(SYSCTL_SYSDIV_5|SYSCTL_USE_PLL|SYSCTL_XTAL_16MHZ|SYSCTL_OSC_MAIN);
    
         // Timer 2 setup code
         SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER2);           // enable Timer 2 periph clks
         TimerConfigure(TIMER2_BASE, TIMER_CFG_PERIODIC);        // cfg Timer 2 mode - periodic
    
         ui32Period = (SysCtlClockGet() / 2);                     // period = CPU clk div 2 (500ms)
         TimerLoadSet(TIMER2_BASE, TIMER_A, ui32Period);         // set Timer 2 period
    
         TimerIntEnable(TIMER2_BASE, TIMER_TIMA_TIMEOUT);        // enables Timer 2 to interrupt CPU
    
         TimerEnable(TIMER2_BASE, TIMER_A);                      // enable Timer 2
    
    
    }
    
    
    int main(void)
     {
         /* Call board init functions */
         Board_initGeneral();
         Board_initGPIO();
         hardware_init();
         Hwi_Params hwiParams;
         Hwi_Handle myHwi;
         Hwi_Params_init(&hwiParams);
    	 
    	 /* Set myIsr5 parameters */
         hwiParams.arg = 10;
         hwiParams.enableInt = FALSE;
         myHwi = Hwi_create(39, (Hwi_FuncPtr)myIsr5, &hwiParams, NULL);
         System_printf("Entering into Hwi");
         System_flush();
         if (myHwi == NULL) {
    	System_abort("Hwi create failed");
    	System_flush();
         }
         Hwi_enableInterrupt(39); 
         BIOS_start();
         return (0);
     }
    

    Therefore these are my questions.

    1. Why Idle function is not running??

    2. TimerLoadSet(TIMER2_BASE, TIMER_A, ui32Period); From the above code I infer that the interrupt is occurring at every 500ms How to calculate the period for different millisecond value (like 1000ms,200ms, 50ms..) I can't understand the above API..

    3. ui32Period = (SysCtlClockGet() / 2);  I have set breakpoint in the above code that shows that the value of ui32Period is 512... What does it mean??? Is it certain register value... If so what is that name of that register?? 

    With regards,

    Naveen Kumar 

  • Can you show your cfg file? Do you have the User defined Idle function? See below. Also place a breakpoint in  myIdleFunc() and check if the Hwi5 is true or false. 

    The ui32Period comes from the line ui32Period = (SysCtlClockGet() / 2); However, the ui32Period is a API for TM4C123, not for TM4C129. I was showing you an example how to setup the Timer and didn't realize that you are using the TM4C129. You can replace the ui32Period with your desired timer period. For TM4C123 the SysCtlClockGet() returns the operating frequency in terms of number of CPU cycles in one seconds. With SysCtlClockGet() / 2 it is equal to number of cycles in 500ms. Anyway, you cannot use this API.