xSemaphoreTake(semhandle, 0) seems to create deadlock

developb wrote on Wednesday, May 15, 2019:

Kindly verify code below: (it seems to cause deadlock at times especially initially)

Platform : STM32, Using HAL for driver code.
Gist of code: UART rx and tx as a periodic task using vTaskDelayUntil(xx). Rx and Tx using DMA
No of tasks:2 where one task acts as bottom half of rx interrupt handler and the other task is main user task.
synchronization primitives used: 2 binary semaphores - one between interrupt handler and its bottom half and the other between user task and the bottom half of interrupt handler. But, bottom half doesn’t call blocking call for xSemaphoreTake() for semaphore it is sharing/using between main task.

Rx interrupt handler calls “xSemaphoreGiveFromISR( xSemaphore1Handle, &xHigherPriorityTaskWoken);”
where “vHandlerTaskRx()” acting as bottom half of the rx interrupt and does memcpy of received data to used by user task.

int main(void)
 {
  HAL_Init();
  SystemClock_Config();
  MX_GPIO_Init();
  MX_DMA_Init();
  MX_USART6_UART_Init();

  TaskHandle_t  handle;
  osSemaphoreDef(xSemaphore1);
  xSemaphore1Handle = osSemaphoreCreate(osSemaphore(xSemaphore1), 1);

  osSemaphoreDef(xSemaphore2);
  xSemaphore2Handle = osSemaphoreCreate(osSemaphore(xSemaphore2), 1);

  if( xSemaphore1Handle != NULL )
  {
	 xTaskCreate( vHandlerTaskRx, "Handler", 400, NULL, 8, NULL );
	  if(xTaskCreate( main_task, "maintask", 1000, NULL, 6, &handle) != pdPASS)
	  {
          Error_Handler();
	  }

	  osKernelStart();
  }
  

  while (1)
  {

  }
  
}

void main_task(void *pvParameters)
{
	TickType_t xLastWakeTime;
	

	while(t<t1)
	{
		ret = HAL_UART_Receive_DMA(&huart6, rx_data, 64);
		if(ret != HAL_OK) {}
		

		if(xSemaphoreTake(xSemaphore2Handle, NULL) == pdTRUE)
		{
			memcpy(Plane_state,Plane_state_rx[2],60);
			xSemaphoreGive(xSemaphore2Handle );
		}

		----
        ----
        ----
	 	vTaskDelayUntil(&xLastWakeTime, xPeriod);

		ret = HAL_UART_Transmit_DMA(&huart6, txdata, 36);
		if(ret != HAL_OK) {}
	}
}

static void vHandlerTaskRx( void *pvParameters )
{
        while(1)
        {
                xSemaphoreTake( xSemaphore1Handle, portMAX_DELAY );
                if(xSemaphoreTake( xSemaphore2Handle, 0) == pdTRUE)
                {                
                	memcpy(Plane_state_rx,rx_data,64);
                	xSemaphoreGive(xSemaphore2Handle );
                }
                
        }
}

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
 BaseType_t xHigherPriorityTaskWoken;
	xHigherPriorityTaskWoken = pdFALSE;


	xSemaphoreGiveFromISR( xSemaphore1Handle, &xHigherPriorityTaskWoken);
}

Thanks

rtel wrote on Wednesday, May 15, 2019:

Nothing obvious but I don’t know what osSemaphoreDef() or
osSemaphoreCreate() are doing. If osSemaphoreDef() is declaring a
semaphore handle on the stack of main() then that might be the problem
as that stack will get overwritten by any stack used by interrupts after
the scheduler has started.