xSemaphoreGiveFromISR failed?

Hi,

I’m using freertos 8.2.3, and I meet a problem of xSemaphore.

I used xSemaphore successful in one of my project. but when I use it the same way in another project, it failed to give semaphore. the latter project is derived from the former one. and I compared FreeRTOSConfig.h in the two project, they are the same.

the program stopped at xSemaphoreGiveFromISR. any other factor can influence semaphore?

the way I use xSemaphore is like this:

=================================
in .h file

    SemaphoreHandle_t data_ready_sem;

in .c file

in one function:

data_ready_sem = xSemaphoreCreateBinary();
if( data_ready_sem == NULL ){
	ERROR_RESIN("data_ready_sem create failed\r\n");
}

// init some variable

xSemaphoreTake(data_ready_sem, portMAX_DELAY);

in timer fired handler:

    xSemaphoreGiveFromISR(data_ready_sem, &xHigherPriorityTaskWoken2);

What do you mean with a “timer fired handler”? Is that a hardware timer causing an ISR?
Or is that a handler that is called from the timer module?
And if so, I think you should use xSemaphoreGive() because the code runs in the context of the timer task.

Maybe the code stops in a configASSERT(), have you checked that?

I’m using freertos 8.2.3

That version works perfectly, but it is recommended to use the latest version for new developments.

Hi, Hein Tibosch

Thanks for your reply.

I tried xSemaphoreGive() and it stopped at xSemaphoreTake(data_ready_sem, portMAX_DELAY);

I dig into xSemaphoreTake and find it stopped at ‘portYIELD_WITHIN_API();’

I’ll dig into xSemaphoreGiveFromISR and try to find where the program stops.

if I use xSemaphoreGiveFromISR

it stops at
portASSERT_IF_INTERRUPT_PRIORITY_INVALID();

Can you tell from where you call xSemaphoreGiveFromISR()?
Is that from an ISR or from a normal task context?

Hi,

the mcu is atsams70 from atmel, which has contex v7 core.

xSemaphoreGiveFromISR()is call from
void TC1_Handler(void)
which is a hardware timer handler.

the timer confige is like this:

‘void configure_tc1(void)
{
uint32_t ul_perclk = sysclk_get_peripheral_hz();
uint32_t ul_rc_time = 0;

/* Enable peripheral clock. */
pmc_enable_periph_clk(ID_TC1);

tc_init(TC0, TC1_CHANNEL,
TC_CMR_TCCLKS_TIMER_CLOCK2 | //MCK/8
TC_CMR_WAVE |                //waveform mode
TC_CMR_WAVSEL_UP_RC |        //count up, reset on RC match
TC_CMR_ACPA_CLEAR |          //clear TIOA0 on match with RA
TC_CMR_ACPC_SET              //Set TIOA0 on match with RC
);

ul_rc_time = (uint32_t)((float)ul_perclk/8.0/200000);

TC0->TC_CHANNEL[TC1_CHANNEL].TC_RA = ul_rc_time / 2;
TC0->TC_CHANNEL[TC1_CHANNEL].TC_RC = ul_rc_time;

/* Configure and enable interrupt on RC compare */
NVIC_EnableIRQ((IRQn_Type) ID_TC1);
tc_enable_interrupt(TC0, TC1_CHANNEL, TC_IER_CPCS);

}’

it is a hardware timer.

Sounds like an interrupt priority issue of the timer. Did you call NVIC_SetPriority with an appropriate priority somewhere ?
In addition please see this

and Richard’s follow up.

You should better not define global variables like data_ready_sem in a header file.
Just declare it extern SemaphoreHandle_t data_ready_sem; and define it in one c-file if you want to use it (as a global variable) in multiple c-files later on.
If it’s intended use is limited to a single c-file (e.g. the timer driver/task module) better define it as static SemaphoreHandle_t data_ready_sem; in this c-file.
Just a hint and to avoid unexpected ‘multiple definitions’ errors if you include the header file in another c-file later on.

1 Like

yes, It is a problem of NVIC_SetPriority, I did not call this funciton as I’m not very clear with functions like NVIC_*.

any recommend documents/web page about these functions or about CMSIS?

Luckily only a small fraction of the CMSIS API is needed controlling the NVIC.
See e.g. the related ARM docs and the provided CMSIS (core) sources.

1 Like