xSemaphoreTake function looping at configASSERT( pxQueue->uxItemSize == 0 );

rohitsay89 wrote on Thursday, October 17, 2019:

Hi I am trying to implement a binary semaphore using CMSIS V2 on stm32cube MX pre generated code. I see that the semaphore acquire function is hanging on line configASSERT( pxQueue->uxItemSize == 0 ); in xQueueSemaphoreTake function in queue.c. I am not sure why is this happening, I am not using the semaphore anywhere else.

void command_1(uint8_t cmd){
	osStatus_t local_status;
	uart_print_t local_msg;

	local_status = osSemaphoreAcquire(COMSemaphoreHandle, 0);
	if(local_status == osOK){
		strcpy(local_msg.msg, "Hello from command task\r\n");
		osMessageQueuePut(uartQueue01Handle, &local_msg, 0, osWaitForever);
	}
	local_status = osSemaphoreRelease(COMSemaphoreHandle);
}

The osSemaphoreAcquire and osSemaphoreRelease are CMSIS V2 wrapper functions for the FreeRTOS xQueueSemaphoreTake and xQueueSemaphoreGive functions. Any help is appriciated.
Thanks,
Rohit

1 Like

rtel wrote on Thursday, October 17, 2019:

The semaphores in FreeRTOS are, for historic reasons of minimising code
size, implemented as queues that have an item size of zero. If you
create a ‘queue’ using one of the semaphore create functions (binary,
counting, mutex, recursive being the types of semaphore you can create)
then the item size will be zero. If you then call a semaphore give or
take function it checks the parameter passed in has an item size of zero
because if it doesn’t then it was not created by one of the semaphore
create function and is therefore not valid to pass into a semaphore API
function. If you did create the semaphore with a valid semaphore create
function, and the assert still fails, then it is likely that the
semaphore’s data structure has been corrupted.

rohitsay89 wrote on Thursday, October 17, 2019:

Thanks for your quick reply on this, I made sure that the binary semaphore is generated correctly from the xSemaphoreCreateBinary() function. Also I single stepped and made sure the itemsize is zero when it was being created. After the creation I go to the place where it is used and see that in xQueueSemaphoreTake, that the following is the item size.

uxItemSize	UBaseType_t	0x20001050 (Hex)	

It seems to be some kind of address to a SRAM location. Just FYI, I am not using any optimizations and I am creating the semaphore in main.c file but using it in another file, also I am doing an extern for that semaphore handle variable.

In cubemx i tried creating the same binary semaphore as a statically allocated then it works perfectly fine. I am not sure how semaphore is getting corrupted.
Any suggestions are appreciated.

rtel wrote on Thursday, October 17, 2019:

I am not familiar with the CMSIS API but thought the Cube software
already had these semaphore APIs for FreeRTOS - is the binary semaphore
one missing (curious as to why you are trying to create this yourself)?

If your debug system enables data watch points then you can set a break
point on a write to the address of the item size after it has been set
to 0 to find where it gets overwritten.

rohitsay89 wrote on Thursday, October 17, 2019:

I found it !
I am using sprintf in another task to create a string and append an uint8_t variable to it. When I use the watchpoints as mentioned in previous therad, I saw that the memory location was written by corrupted by sprintf and was never recovered back to be used by semaphore. So the SRAM location for item size has that corrupted value and when it is being read by config assert it hangs the processor to that infinite loop.
I removed that sprintf and kept the bin semaphore as dynamic allocation, and it works perfectly fine. I am using strcpy for now. Is there any better alternative to sprintf for int and floats ?

To answer your question, Cube MX software has that visual tool to generate and configure all the required peripherals and FreeRTOS configurations as well, it has binary semaphore also.

Thanks for your help ! I hope this thread does help someone who needs it
Regards,
Rohit