Mutex "give" occurs when another task already owns mutex. V9.0

zempter wrote on Monday, September 25, 2017:

I have checked to make sure that all of the tasks that take ownership of the mutex give it back imediately after the important function call that interacts with a non-thread-safe libary. However, when The tasks are operating, not very long into startup (but not imediately, so it works for a little while) My “periodics” task tries to give up my mutex that says it is currently owned by my “matrix” task.

xTaskPriorityDisinherit then thows at configASSERT( pxTCB == pxCurrentTCB ); because the current owner is wrong.

I want to understand what could be causing it, but my boss wants me to just toss everything that interracts with that library into one task to avoid the problem from happening. It is bugging me like crazy though, and I will have to do a decent amount of restructuring to my code that I feel like would be unfortunate.

What could be causing this? I am operating on a single core Cypress chip. My config header looks like this:

###ifndef FREERTOS_CONFIG_H
###define FREERTOS_CONFIG_H

/* Here is a good place to include header files that are required across

your application. */

###include “project.h”

###define configUSE_PREEMPTION 1
###define configUSE_PORT_OPTIMISED_TASK_SELECTION 0
###define configUSE_TICKLESS_IDLE 0

// PSoC Creator creates a #define macro for the clock settings from the DWR

###define configCPU_CLOCK_HZ ( ( unsigned long ) CYDEV_BCLKSYSCLKHZ )

// SysTick Defaults to 1ms

###define configTICK_RATE_HZ 1000
###define configMAX_PRIORITIES 5
###define configMINIMAL_STACK_SIZE 128
###define configMAX_TASK_NAME_LEN 16
###define configUSE_16_BIT_TICKS 0
###define configIDLE_SHOULD_YIELD 1
###define configUSE_TASK_NOTIFICATIONS 1
###define configUSE_MUTEXES 1
###define configUSE_RECURSIVE_MUTEXES 0
###define configUSE_COUNTING_SEMAPHORES 1
###define configUSE_ALTERNATIVE_API 0 /* Deprecated! */
###define configQUEUE_REGISTRY_SIZE 10
###define configUSE_QUEUE_SETS 1
###define configUSE_TIME_SLICING 0
###define configUSE_NEWLIB_REENTRANT 0
###define configENABLE_BACKWARD_COMPATIBILITY 0
###define configNUM_THREAD_LOCAL_STORAGE_POINTERS 5

/* Memory allocation related definitions. */

###define configSUPPORT_STATIC_ALLOCATION 0
###define configSUPPORT_DYNAMIC_ALLOCATION 1
###define configTOTAL_HEAP_SIZE 7000
###define configAPPLICATION_ALLOCATED_HEAP 0

/* Hook function related definitions. */

###define configUSE_IDLE_HOOK 0
###define configUSE_TICK_HOOK 0
###define configCHECK_FOR_STACK_OVERFLOW 0
###define configUSE_MALLOC_FAILED_HOOK 0
###define configUSE_DAEMON_TASK_STARTUP_HOOK 0

/* Run time and task stats gathering related definitions. */

###define configGENERATE_RUN_TIME_STATS 0
###define configUSE_TRACE_FACILITY 0
###define configUSE_STATS_FORMATTING_FUNCTIONS 0

/* Co-routine related definitions. */

###define configUSE_CO_ROUTINES 0
###define configMAX_CO_ROUTINE_PRIORITIES 1

/* Software timer related definitions. */

###define configUSE_TIMERS 1
###define configTIMER_TASK_PRIORITY 3
###define configTIMER_QUEUE_LENGTH 10
###define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE

/* Interrupt nesting behaviour configuration. */

###define configKERNEL_INTERRUPT_PRIORITY [dependent of processor]
###define configMAX_SYSCALL_INTERRUPT_PRIORITY [dependent on processor and application]
###define configMAX_API_CALL_INTERRUPT_PRIORITY [dependent on processor and application]

/* Define to trap errors during development. */

###define configASSERT( x ) if( ( x ) == 0 ) { taskDISABLE_INTERRUPTS(); for( ;; ); }

/* FreeRTOS MPU specific definitions. */

###define configINCLUDE_APPLICATION_DEFINED_PRIVILEGED_FUNCTIONS 0

/* Optional functions - most linkers will remove unused functions anyway. */

###define INCLUDE_vTaskPrioritySet 1
###define INCLUDE_uxTaskPriorityGet 1
###define INCLUDE_vTaskDelete 1
###define INCLUDE_vTaskSuspend 1
###define INCLUDE_xResumeFromISR 1
###define INCLUDE_vTaskDelayUntil 1
###define INCLUDE_vTaskDelay 1
###define INCLUDE_xTaskGetSchedulerState 1
###define INCLUDE_xTaskGetCurrentTaskHandle 1
###define INCLUDE_uxTaskGetStackHighWaterMark 0
###define INCLUDE_xTaskGetIdleTaskHandle 0
###define INCLUDE_eTaskGetState 0
###define INCLUDE_xEventGroupSetBitFromISR 1
###define INCLUDE_xTimerPendFunctionCall 0
###define INCLUDE_xTaskAbortDelay 0
###define INCLUDE_xTaskGetHandle 0
###define INCLUDE_xTaskResumeFromISR 1

/* A header file that defines trace macro can be included here. */

###endif /* FREERTOS_CONFIG_H /*

rtel wrote on Monday, September 25, 2017:

Are you giving the mutex from an interrupt at all? That can really mess
up what the system thinks is the mutex owner.

zempter wrote on Monday, September 25, 2017:

Nevermind, I figured it out, I was using the wrong delay value.

xSemaphoreTake(MATRIX_MUTEX,0);

when I really wanted:

xSemaphoreTake(MATRIX_MUTEX,portMAX_DELAY );

I was thinking that 0 meant it didn’t have a timeout.

zempter wrote on Monday, September 25, 2017:

I wasn’t ever calling from an interrupt.

Thanks for the fast response.

richard_damon wrote on Tuesday, September 26, 2017:

You also should be testing the return value of the take to make sure you got it. That would have cought the error.