cancel
Showing results for 
Search instead for 
Did you mean: 

Hard fault in ThreadX tx_mutex_put

nicgreenway
Associate II

Hi All

I have a problem with a ThreadX-based project on a Nucleo H563ZI board when using a mutex.

The mutex locks access to an FDCAN peripheral, and a message-buffer data structure during CAN-FD message transmission.  The problem only shows up when I load-test the system by running a tight loop on a thread attempting to send messages continuously; there is a separate thread will will send heartbeat messages at a much lower rate.

After a seemingly random amount of time (typically of the order of 10 seconds, equating to usually 50,000-100,000 mutex accesses) the code hard-faults in tx_mutex_put.c, at line 386, snippet below.  The fault is at the check for `(mutex_ptr -> tx_mutex_owner) -> tx_thread_priority;` at this point mutex_ptr->tx_mutex_owner is null, hence the crash.

I can workaround it by putting a check for (mutex_ptr->tx_mutex_owner != TX_NULL) around the if block, but I don't feel comfortable with this, it feels like covering up the symptom rather than addressing the cause.

I have checked all tx_mutex_get calls return TX_SUCCESS.  I have tried toggling the TX_NOT_INTERRUPTABLE flag in tx_user.h.  I have tried wrapping the mutex calls in C++ classes to allow use of a lock-guard (to be sure there are no mismatches in gets and puts) - nothing makes any difference except the fix in tx_mutex_put.c

There are two callback interrupts from the FDCAN peripherals, but the only ThreadX operations they perform is setting a semaphore. As suggested at https://stackoverflow.com/questions/72200459/tx-semaphore-inside-a-interrupt I tried adding _tx_thread_context_save/restore into the interrupts, but this made no difference either (probably to be expected based on https://community.st.com/t5/stm32-mcus-embedded-software/requirement-to-call-tx-thread-context-save-restore-for-various/td-p/718770 )

 

Could anyone give me any pointers on where to look next?

Any advice appreciated!

Nic

 

Snippet from tx_mutex_put:

/* Mutex is not owned, but it is possible that a thread that
caused a priority inheritance to occur is no longer waiting
on the mutex. */

/* Setup the highest priority waiting thread. */
mutex_ptr -> tx_mutex_highest_priority_waiting = (UINT) TX_MAX_PRIORITIES;

/* Determine if we need to restore priority. */
if ((mutex_ptr -> tx_mutex_owner) -> tx_thread_priority != old_priority)
{

/* Yes, restore the priority of thread. */
_tx_mutex_priority_change(mutex_ptr -> tx_mutex_owner, old_priority);
}

 

 

0 REPLIES 0