Call to vSemaphoreCreateBinary ends in

I have a strange behaviour.
When I call vSemaphoreCreateBinary() it ends up in

portFORCE_INLINE static void vPortRaiseBASEPRI(void)
{
	uint32_t ulNewBASEPRI;

	__asm volatile("	mov %0, %1												\n"

By this time everything is stopped.
Could someone give a clue about this?

thanks

You should add which FreeRTOS port and version you’re using.
What does it mean everything is stopped ?

Hint: Please enclose code blocks in 3 tildas (~~~) or 3 backticks (```) and try to align/format the code for better readability :slight_smile:

Sorry I wrote the post too fast… :slight_smile:

FreeRTOS 10.0 on a ATSAMV71.

A semaphore is created by a task as

int csp_bin_sem_create(csp_bin_sem_handle_t * sem) {
->	vSemaphoreCreateBinary(*sem);
	return CSP_SEMAPHORE_OK;
->}

I have 2 breakpoints on the lines with a →
The first is hit, the second is not!

When I pause the debugger it’s on the line below shown with a =>

portFORCE_INLINE static void vPortRaiseBASEPRI(void)
{
	uint32_t ulNewBASEPRI;

=>	__asm volatile("	mov %0, %1												\n"

Being this a C inline function defined on a C macro may contribute to what I’m experiencing…
If I try to single-step the debugger instead runs, and if I pause it again it shows as being at the same line. No matter what I do, it seems the debugger is incapable of proceeding.

I bet it just SEEMS like the program is stuck there because vPortRaiseBASEPRI can’t hang (normally).
Is it possible that the application has stopped itself in a configASSERT (forever loop) ?
Do you have compiler optimization OFF (-O0) and configASSERT along with the other FreeRTOS debug utilities enabled (as recommended) ?
What’s the call stack when halting the target ?

This code is part of CSP a CubeSat Space Protocol.
I’m intrigued with the way of calling vSemaphoreCreateBinary…
Passing not an address like &sem (or in this case just sem) but instead passing *sem!!!

I’m not familiar with CSP, but the wrapper API has a handle pointer argument and vSemaphoreCreateBinary (macro) wants a handle (which in fact is a pointer). That’s not the problem.
I guess csp_bin_sem_handle_t just an alias for SemaphoreHandle_t.
Did you verify that the provided sem pointer is valid when calling csp_bin_sem_create ?

This is the call stack

> CSPproject.elf! vPortRaiseBASEPRI Line: 195
CSPproject.elf! xQueueGenericSend (QueueHandle_t xQueue, const void * const pvItemToQueue, const void * const pvItemToQueue@entry, TickType_t xTicksToWait, TickType_t xTicksToWait@entry, const BaseType_t xCopyPosition, const BaseType_t xCopyPosition@entry) Line: 710
CSPproject.elf! csp_bin_sem_create (csp_bin_sem_handle_t * sem, csp_bin_sem_handle_t * sem@entry) Line: 46
CSPproject.elf! csp_conn_init Line: 104
CSPproject.elf! csp_init (const csp_conf_t * conf, const csp_conf_t * conf@entry) Line: 52
CSPproject.elf! main_CSP_task (void * p) Line: 209
CSPproject.elf! uxListRemove (ListItem_t * const pxItemToRemove) Line: 191

csp_bin_sem_handle_t is the same as xSemaphoreHandle

typedef xSemaphoreHandle csp_bin_sem_handle_t;

Again: Do you have configASSERT defined ? That’s incredibly helpful for development !
It catches quite a number of application code bugs like in this case.
You see, for an unknown reason creating a binary semaphore fails badly. You can be very sure that the FreeRTOS code creating a binary semaphore is not buggy.
So the problem is most likely caused by calling application code.
All the configASSERTs in FreeRTOS code ensure as good as possible, that the API contracts are not violated.

I believe so

It’s define in FreeRTOSConfig.h as:

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

And if I put an error in it, the compiler catches it so it must be in use.

The code that is calling the creation of the semaphore in short is like this:

typedef xSemaphoreHandle csp_bin_sem_handle_t;

static csp_bin_sem_handle_t conn_lock;

	if (csp_bin_sem_create(&conn_lock) != CSP_SEMAPHORE_OK) {
		csp_log_error("csp_bin_sem_create(&conn_lock) failed");
		return CSP_ERR_NOMEM;
	}

int csp_bin_sem_create(csp_bin_sem_handle_t * sem) {
	vSemaphoreCreateBinary(*sem);
	return CSP_SEMAPHORE_OK;
}

Here we go: taskDISABLE_INTERRUPTS finally calls vPortRaiseBASEPRI…
Seems a configASSERT failed and it just looks like the program hangs in vPortRaiseBASEPRI. In fact it’s just looping forever in for (;;).
So I’d step into csp_bin_sem_create to find the exact configASSERT statement which fails and you hopefully get an idea what the root cause problem in your code is.

Edit: The csp_bin_sem_create wrapper and the provided handle seem to be ok.

In

BaseType_t xQueueGenericSend(QueueHandle_t xQueue, const void *const pvItemToQueue, TickType_t xTicksToWait,
                             const BaseType_t xCopyPosition)
{
	BaseType_t     xEntryTimeSet = pdFALSE, xYieldRequired;
	TimeOut_t      xTimeOut;
	Queue_t *const pxQueue = (Queue_t *)xQueue;

	configASSERT(pxQueue);
->	configASSERT(!((pvItemToQueue == NULL) && (pxQueue->uxItemSize != (UBaseType_t)0U)));

xQueue is 0x1000 and pxQueue->uxItemSize is 1176510770 :frowning:

Since xQueue is a pointer this value must be very wrong.
According to the linker file the RAM is:

ram (rwx)   : ORIGIN = 0x20400000, LENGTH = 0x00060000 /* ram, 393216K */

A corrupted pxQueue->uxItemSize was often an indicator for stack overflows here in the forum (search: pxQueue->uxItemSize).
Besides defining configASSERT do you have also stack overflow checking enabled (for development/debugging) ?

Indeed

The stack was very small…
#define TASK_EXAMPLE_STACK_SIZE (128 / sizeof(portSTACK_TYPE))

Copy and Paste, the best way of creating bugs… I copied this from an Atmel example that blinked a LED…

Congrats @eduardo-semcon :+1:
And I hope you achieved the next level with your debugging :space_invader: skills :sunglasses:

1 Like