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/TM4C1294NCPDT: ISR and CALLBACK functions in TI-RTOS

Part Number: TM4C1294NCPDT

Tool/software: TI-RTOS

Respected sir,

                    I am new to TI-RTOS. I am having difficult time understanding  ISR handling and  CALLBACK function. I am trying to understand  "uartecho_TivaTM4C1294NCPDT" example. So please shed some light on

1. How to enable interrupts and create ISR in TI RTOS?

2. What are callback functions and how to use them?

If there are any documents regarding this issue please share.

Regards,

DIgvijay

  • Hello Digvijay,

    The SYS/BIOS TI-RTOS Kernel User's Guide covers interrupts with the Hardware Interrupt (HWI) and Software Interrupt (SWI) sections 3.4 and 3.5 respectively: www.ti.com/.../spruex3t.pdf

    I will loop in the TI-RTOS team regarding callback functions.
  • Hello Digvijay,

    A callback function is an application specific function that is called after a particular event. The UART driver may invoke the callback function from the ISR.  That is, the callback function is called from an interrupt context.

    The application will need to specify the callback function to a particular driver. For example:

    UART_Handle handle;
    UART_Params uartParams;
    
    /* Create a UART with the parameters below. */
    UART_Params_init(&uartParams);
    uartParams.writeMode = UART_MODE_CALLBACK;
    uartParams.readMode = UART_MODE_CALLBACK;
    uartParams.writeCallback = &writeCallback;
    uartParams.readCallback = &readCallback;

    The point of the callback function is to give the application an opportunity to "do something" in the interrupt service routine. For example, when the UART driver receives an UART interrupt, you may want to: post a semaphore, toggle a GPIO or LED...etc.

    Derrick

  • Respected sir,

                       I am trying to create driver for CAN. I am able to transmit data successfully. In receiver operation i need to generate interrupt. But i am getting following error.

    FSR = 0x0000
    HFSR = 0x40000000
    DFSR = 0x0000000b
    MMAR = 0xe000ed34
    BFAR = 0xe000ed38
    AFSR = 0x00000000
    Terminating execution...

                      I have enabled following interrupts

        Hwi_construct(&(object->hwi), hwAttrs->intNum, CANTiva_hwiIntFxn,
                      &(paramsUnion.hwiParams), NULL);

        CANIntEnable(hwAttrs->baseAddr,
                     CAN_INT_MASTER |               //allow CAN controller to generate interrupts, must be enabled.
                     CAN_INT_ERROR |                //the controller enters the “bus off” condition, or if the error counters reach a limit.
                     CAN_INT_STATUS);

      

                              So please suggest me where i am doing mistake.

    regards,

    digvijay

  • Digvijay,

    Is your application crashing when calling CANIntEnable()? If so, you may need to turn on the clocks to the CAN controller.

    Derrick

  • Respected sir,

           My application does not crash while calling  CANIntEnable(). The CAN ISR works fine for  transmit operation. For receive operation , the control goes into ISR after receiving message generates interrupt. I am not able to understand what happens in ISR.  The control goes into following if loop and terminates application.

       // If the cause is a controller status interrupt, then get the status

        if(ui32Status == CAN_INT_INTID_STATUS)

       {

           // Read the controller status.  This will return a field of status

           // error bits that can indicate various errors.  Error processing

           // is not done in this example for simplicity.  Refer to the

           // API documentation for details about the error status bits.

           // The act of reading this status will clear the interrupt.  If the

           // CAN peripheral is not connected to a CAN bus with other CAN devices

           // present, then errors will occur and will be indicated in the

           // controller status.

            ui32Status = CANStatusGet(CAN1_BASE, CAN_STS_CONTROL);

            // Set a flag to indicate some errors may have occurred.

           g_bErrFlag = 1;

       }

    The READ and ISR routines are attached. LED's and readbuf have been used for debugging.

    New Text Document.txt
    int CANTiva_read(CAN_Handle handle,uint8_t *readdata)
    {
        unsigned int        key;
        CANTiva_Object    *object = handle->object;
        CANTiva_HWAttrs const    *hwAttrs = handle->hwAttrs;
    
    
    	 tCANMsgObject sCANMessage;
    	 uint32_t ui32MsgData;
    	 uint8_t *pui8MsgData;
    	 pui8MsgData = (uint8_t *)&ui32MsgData;
    	 unsigned int uIdx,i;
    
    
    	 object->readBuf = readdata;
    	 *((unsigned char *)object->readBuf) = 0xaa;
    //	 *readdata = 0xaa;
         //
         // Initialize a message object to be used for receiving CAN messages with
         // any CAN ID.  In order to receive any CAN ID, the ID and mask must both
         // be set to 0, and the ID filter enabled.
         //
    	 ui32MsgData = 0;
         sCANMessage.ui32MsgID = 0;
         sCANMessage.ui32MsgIDMask = 0;
         sCANMessage.ui32Flags = MSG_OBJ_RX_INT_ENABLE | MSG_OBJ_USE_ID_FILTER;
         sCANMessage.ui32MsgLen = 8;
    
    
         // Now load the message object into the CAN peripheral.  Once loaded the
         // CAN will receive any message on the bus, and an interrupt will occur.
         // Use message object 1 for receiving messages (this is not the same as
         // the CAN ID which can be any value in this example).
         //
         CANMessageSet(hwAttrs->baseAddr, 1, &sCANMessage, MSG_OBJ_TYPE_RX);
     
        return (0);
    }
    
    
    
    static void CANTiva_hwiIntFxn(UArg arg)
    {
    
        SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOF);            //TO CHECK TIME PERIOD OF WAVEFORM
    
        // Enable the GPIO pins for the LEDs (PN0 & PN1).
        GPIOPinTypeGPIOOutput(GPIO_PORTF_BASE, GPIO_PIN_0 | GPIO_PIN_4);
    
        uint32_t                   status,i;
        CANTiva_Object           *object = ((CAN_Handle)arg)->object;
        CANTiva_HWAttrs const    *hwAttrs = ((CAN_Handle)arg)->hwAttrs;
    
        uint32_t ui32Status;
       
    
        // Read the CAN interrupt status to find the cause of the interrupt
        ui32Status = CANIntStatus(hwAttrs->baseAddr, CAN_INT_STS_CAUSE);
    
    
       *((unsigned char *)object->readBuf) = 0xbb;
        GPIO_write(0, ~0);
    
      
    
      // If the cause is a controller status interrupt, then get the status
         if(ui32Status == CAN_INT_INTID_STATUS)
        {
    
        	 GPIO_write(1, 1);
            // Read the controller status.  This will return a field of status
            // error bits that can indicate various errors.  Error processing
            // is not done in this example for simplicity.  Refer to the
            // API documentation for details about the error status bits.
            // The act of reading this status will clear the interrupt.  If the
            // CAN peripheral is not connected to a CAN bus with other CAN devices
            // present, then errors will occur and will be indicated in the
            // controller status.
             ui32Status = CANStatusGet(hwAttrs->baseAddr, CAN_STS_CONTROL);
    
             *((unsigned char *)object->readBuf) = 0x11;
    
             // Set a flag to indicate some errors may have occurred.
             object->g_bErrFlag = 1;
        }
    
    
    
         // Check if the cause is message object 1, which what we are using for
        // receiving messages.
    
         else if(ui32Status == 1)
        {
    
            // Getting to this point means that the TX interrupt occurred on
            // message object 1, and the message TX is complete.  Clear the
            // message object interrupt.
            CANIntClear(hwAttrs->baseAddr, 1);
            //
            // Set flag to indicate received message is pending.
            //
            object->g_bRXFlag = 1;
            *((unsigned char *)object->readBuf) = 0xcc;
    
    
    
            CANread(object , hwAttrs);
    
    
    
            
            object->g_bErrFlag = 0;
        }
    
         else if(ui32Status == 2)
         {
        	 GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_0, 1);
    
        	 CANIntClear(hwAttrs->baseAddr, 2);
        	 // Increment a counter to keep track of how many messages have been
        	        // sent.  In a real application this could be used to set flags to
        	        // indicate when a message is sent.
        	       // g_ui32MsgCount++;
         }
    
        // Otherwise, something unexpected caused the interrupt.  This should
        // never happen.
         else
        {
              // Spurious interrupt handling can go here.
        }
    
         GPIOPinWrite(GPIO_PORTF_BASE, GPIO_PIN_4, 16);
    }
    
    
    
    
    
    
    
    FSR = 0x0000
    HFSR = 0x40000000
    DFSR = 0x0000000b
    MMAR = 0xe000ed34
    BFAR = 0xe000ed38
    AFSR = 0x00000000

    regards

    digvijay

  • Digvijay,

    Have you checked if ui32Status has any other bits set? If so, your if;else case could ail.

    Can you try doing bitwise AND operations?

    if(ui32Status & CAN_INT_INTID_STATUS)
    {
    
    }
    else if(ui32Status & 0x1)
    {
    
    }
    else if(ui32Status & 0x2)
    {
    
    }

  • Respected sir,

     Problem is solved. Added infinite while loop after receive operation and it started working. Anyway thanks for help.

    regards,

    digvijay

  • Let the record show that (somehow) poster (missed) his "Award of Resolved" - to his "Opening/Questioning Post."

  • what do you mean by that??

    regards,
    digvijay