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.

[FAQ] RTOS: Why am I getting a GateMutex Assert in TI-RTOS?

Other Parts Discussed in Thread: SYSBIOS

Tool/software: TI-RTOS

On any device (Sitara, SimpleLink, TM4C, C2000, etc), I get the following runtime error in the console:

ti.sysbios.gates.GateMutex: line 114: assertion failure: A_badContext: bad calling context. See GateMutex API doc for details. xdc.runtime.Error.raise: terminating execution

What is causing this?

  • SYS/BIOS has three different types of threads: Task, SoftWare Interrupt (Swi) and HardWare Interrupt (Hwi). Swis and Hwis are threads that must run to completion without blocking. Tasks can block. There are several areas in SYS/BIOS and the runtime support library (RTS) where blocking can occur. SYS/BIOS has assert checks in place to help a developer avoid calling one of these blocking components within a Hwi or Swi.

    Gates are used to provide critical region management. There are different types of Gates which can be used in various situations. For example:

    ti.sysbios.gates.GateHwi: Disables hardware interrupts when the gate is enter()’d and restores them in the exit().

    ti.sysbios.gates.GateSwi: Disables software interrupts (not Hwi) when the gate is enter()’d and restores them in the exit().

    ti.sysbios.gates.GateMutex: Obtains a binary semaphore when the gate is enter()’d and releases the semaphore in the exit(). If the gate is already owned by another thread, the caller is blocked on a Semaphore_pend.

    ti.sysbios.gates.GateMutexPri: Same as GateMutex, but avoids priority inversion.

    A Swi or Hwi thread should not call GateMutex_enter() since blocking can occur. SYS/BIOS helps developers find cases where this occurs. In GateMutex_enter(), the calling context is checked. If the context is a Swi or Hwi, the GateMutex_A_BadContext assert check fails and the program is terminated. (Note: you can build your application with assert checking turned off). You’ll get the following assert error if you call (directly or indirectly) GateMutex_enter from a Swi or Hwi.

    ti.sysbios.gates.GateMutex: line 114: assertion failure: A_badContext: bad calling context. See GateMutex API doc for details. xdc.runtime.Error.raise: terminating execution

    Unfortunately due to compiler optimizations and the Assert/Error modules design, the back trace cannot be obtained when the target is halted on the failed assert. This issue is being addressed in a future release of SYS/BIOS and/or XDCTools. For now, developers can follow the steps below to help identify the case of the failed assert.

    Reason why Assert occurs

    Below is a description of the cause of the issue and the recommended action to take.

    System_printf or printf

    Cause: Calling System_printf() or printf() from a Swi or Hwi when xdc.runtime.SysStd is your System.SupportProxy.

    var System = xdc.useModule('xdc.runtime.System');
    var SysStd = xdc.useModule('xdc.runtime.SysStd');
    System.SupportProxy = SysStd;

    Action: Remove the System_printf() or printf() from the Swi or Hwi or use xdc.runtime.SysMin instead. Note: SysMin writes to an internal buffer that is flushed to console upon exit() or when System_flush() is called.

    var System = xdc.useModule('xdc.runtime.System');
    var SysMin = xdc.useModule('xdc.runtime.SysMin');
    System.SupportProxy = SysMin;

    HeapMem and malloc

    Cause: Calling HeapMem_alloc() or malloc() from a Swi or Hwi when GateMutex is used (which is the default).

    Action: Remove the allocation from the Swi or Hwi or use different heap implementation (e.g. HeapBuf or HeapMultiBuf).

    Isolating offending code

    Using breakpoints and ROV can help isolate what is causing the GateMutex_A_BadContext assert check failure.

    1. Rebuild the application with RTSC Build-Profile set to debug. This will help give more stack trace information.

    2. Set breakpoints in the following functions.

    _xdc_runtime_System_printf__E
    _ti_sysbios_heaps_HeapMem_alloc__E
    malloc
    printf

    3. Make each of the above breakpoints conditional on the following expression (Breakpoint properties):

    _ti_sysbios_BIOS_Module__state__V.threadType==0 || _ti_sysbios_BIOS_Module__state__V.threadType==1

    4. Run your application and whenever a breakpoint is hit, check ROV if the BIOS.currentThreadType is a Swi or Hwi.

    5. If the currentThreadType is a Swi or Hwi, look at the back-trace to determine where the offending call is being made from. Note: symbols are not include in RTS library, so malloc and printf will show minimal back traces.