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/TM4C123GH6PM: ti.sysbios.family.arm.m3.Hwi: line 1277: E_noIsr: id = 21, pc = XXXXX

Part Number: TM4C123GH6PM
Other Parts Discussed in Thread: SYSBIOS

Tool/software: TI-RTOS

I'm at a loss here. I have been working on a project for quite a while and I ported my working code to a revision of the board that has a few less pins assigned, but otherwise identical. My software is crashing if I leave a UART RX callback function assigned, but if I remove the line where I register my callback (but leave interrupts enabled), everything works fine.

For the record, the offending UART is UART2.  I also have UART1 configured exactly the same in a different task, with its own callback. The UART1 task works fine, but the UART2 task will trigger a crash, although usually not within the running task. Sometimes the crash occurs in the Idle task, and sometimes in the UART1 task. However, it is the IntRegister() call in the UART2 task that will lead to the crash.

Whichever task crashes, the backtrace always ends in with this line: 

ti.sysbios.family.arm.m3.Hwi: line 1277: E_noIsr: id = 21, pc = 00012a38
Exception occurred in background thread at PC = 0x00012a38.
Core 0: Exception occurred in ThreadType_Task.
Task name: {unknown-instance-name}, handle: 0x20006e44.
Task stack base: 0x20002c60.
Task stack size: 0x600.
R0 = 0x00000001  R8  = 0xffffffff
R1 = 0x2000321c  R9  = 0xffffffff
R2 = 0x00000000  R10 = 0xffffffff
R3 = 0x0000001f  R11 = 0xffffffff
R4 = 0xffffffff  R12 = 0x151b0200
R5 = 0xffffffff  SP(R13) = 0x20003240
R6 = 0xffffffff  LR(R14) = 0x000136ed
R7 = 0xffffffff  PC(R15) = 0x00012a38
PSR = 0x61000000
ICSR = 0x0400f815
MMFSR = 0x00
BFSR = 0x00
UFSR = 0x0000
HFSR = 0x00000000
DFSR = 0x0000000b
MMAR = 0xe000ed34
BFAR = 0xe000ed38
AFSR = 0x00000000
Terminating execution...

    GPIOPinTypeUART(PORT_UI_UART_BASE, PIN_UI_RX | PIN_UI_TX);
    GPIOPinConfigure(PIN_UI_UART_TX);
    GPIOPinConfigure(PIN_UI_UART_RX);
    // Set up Baud and characteristics
    UARTConfigSetExpClk(UI_UART_BASE, SysCtlClockGet(), 115200,
        (UART_CONFIG_WLEN_8 | UART_CONFIG_STOP_ONE | UART_CONFIG_PAR_NONE));

    debugPrint("INFO: UserInterface: pins configured\n");

    IntMasterEnable();
    // Call NVIC API commands to set up interrupt handler
    IntRegister(UI_UART_RX_INTERRUPT, UserInterfaceUARTRxInterruptCallback); // <------------- Causing crash!!!!!!!!!!!!!!!!!!!
    // ln 528 interrupt.c

    // Enable interrupts
    IntEnable(UI_UART_RX_INTERRUPT);
    UARTIntEnable(UI_UART_BASE, UART_INT_RX|UART_INT_RT|UART_INT_OE|UART_INT_BE|UART_INT_PE|UART_INT_FE);

Curiously, the Idle task is also using much more stack than it was previously. I increased the stack size to prevent overflow, and the error above is my new reality. Also, it's worth noting that the ISR actually never gets called. It crashes before the ISR is called. It crashes regardless of if UART2 actually sends any data. It hasn't received either (by design - not needed yet) and this crash occurs. I've stepped through the code and both the UART1 and UART2 code correctly execute through the IntRegister() functions, enabling the interrupts I want and registering the callbacks. This is a slightly delayed crash, but I have no idea why because I didn't change anything from my previously known good code.

I've tried everything I've found relating to any of the odd little messages I found in the backtrace, or the RTOS Object Viewer, or forums but nothing has fixed this error other than disabling the IntRegister call. Maybe the silicon gods do not want me to use interrupts and they would rather that I poll for receiving UART data. I don't know, but debugging TI-RTOS crashes is always so frustrating. I've even watched Todd Mullanix's video hoping for something else that I haven't tried. Maybe the board itself is causing a software bug - I have no idea.

  • Hi Mark,

    I expect the problem is the IntRegister call. Please take a look at this thread for a complete description on why IntRegister and TI-RTOS do not mesh well: e2e.ti.com/.../2347913

    Why don't you use the UART driver in TI-RTOS instead using driverlib? If you want to continue to use driverlib, please use the Hwi module to plug the interrupt instead IntRegister.

    Todd
  • I'm using the libraries that I am mostly because I don't know any better. Will you do me a favor and tell me which functions I'm using that are not recommended and list the ones I should replace them with?

    The only thing that I've done to greatly diverge from the original USB/UART example code is I have tried to remove the "Board_initGPIO()" and "Board_initUART()" calls in main.c and to rip out the declarations in EK_TM4C123GXL (i.e., gpioPinConfigurations, uartTivaObjects, etc.).  I did this because I want the areas of my code (tasks) that handle GPIO and UART data to independently and more clearly define for themselves how those peripherals are utilized. I do not like how everything was hidden away under libraries that were not easily accessible in my project. Sure, I could go search through C:\ti\ to go look for the exact version of gpio.h or TIVA_gpio.h that was included and jump around between files to see what those declarations in EK_TM4C123GXL.h actually did, or I could remove those calls and specifically configure them when and how I needed them.

    So, I'm hoping your suggestion is to just use different APIs and not to put all that stuff back into EK_TM4C123GXL.(c,h). <Fingers crossed>

  • Mark,

    Instead of using the Int* APIs (IntMasterEnable(), IntRegister(), etc.) in the TI-RTOS environment, you should be using the Hwi module.

    IntMasterEnable() -> Hwi_enable()
    IntRegister(intnum, isr) -> Hwi_create(intnum, isr, params, NULL)

    In addition, also do
    #include <ti/sysbios/hal/Hwi.h>

    Typically, users don't call Hwi_enable() since enabling global interrupts needs to be under the control of SYS/BIOS.  Global interrupt enable is done in BIOS_start() (which your app should already be calling) and should never be manually enabled before then (e.g., in main()).

    Regards,

    - Rob

  • Thanks! I never would have guessed, so you saved my project. Thanks again. I replaced IntRegister and got rid of IntEnable. I put this in its place:

    /* Install interrupt handler */
    hwi = Hwi_create(UI_UART_RX_INTERRUPT, UserInterfaceUARTRxInterruptCallback, NULL, &eb);
    if (hwi == NULL) {
        System_abort("Can't create UART Hwi");
    }

  • Mark,

    You're most welcome, and thank you for reporting back to the Forum.

    Regards,

    - Rob