xSemaphoreTake gets blocked

I’ve created a simple semaphore mutex into one of the tasks in order to avoid silmultaneous access to a global variable. The code is identical to the one explained in the online tutorial: xSemaphoreHandle xSemaphore = NULL; void myTask(void *pvParameters) {    xSemaphore = xSemaphoreCreateMutex();    … } void myfunction(void) { …    if( xSemaphoreTake( xSemaphore, ( portTickType ) 10 ) == pdTRUE )    {       // Access to the global resource      xSemaphoreGive(epSemaphore);    }    … } … I’ve verified that the semaphore is correctly created. During the first accesses, it’s even "taken" and "released" without problems. However, after some successful accesses, myfunction gets blocked at xSemaphoreTake. Doing xBlockTime = 0 solves the problem but I’d like myfunction to wait at least some ticks before abandoning the semaphore. I’m thinking that maybe FreeRTOS doesn’t know what a tick is in my system so that it waits indefinitely. I’ve maybe missed some definition elsewhere… I understand that my descriptions are quite vague but… has anyone an idea about what could be happening with my setup? Thank you very much, Daniel.

xSemaphoreTake gets blocked

First, put a break point in vTaskIncrementTick() in tasks.c. If the break point is triggered repeatedly then your tick interrupt is working ok. Also do the usual things like checking for stack overflows, things like that.

xSemaphoreTake gets blocked

Thanks Dave for your help. vTaskIncrementTick() is called several times at the beginning of the execution. Then, it’s not called again, matching with the blockage at xSemaphoreTake in myfunction() . I’ve also verified that there is no stack overflow through the use of the vApplicationStackOverflowHook function. Something curious IMO, If I add an instruction in vTaskIncrementTick() that prints a text message on my Dev Board’s OLED display, then vTaskIncrementTick gets called without problems all the time and my program works smoothly.  This is not a valid solution though but I wanted to explain this behavior, just in case this is a symptom about what’s happening. My hardware platform is a Luminary LM3S8962 Eval board. Thanks again! Daniel.

xSemaphoreTake gets blocked

I’ve found the source of the problem. I was using a timer interrupt in order to run ADC conversions on my Stellaris platform. The trigger of this interrupt was hanging the task I think. I now know that custom interrupts have to be avoided under FreeRTOS :-)

xSemaphoreTake gets blocked

I’ve written several FreeRTOS programs that run on Luminary chips.  Interrupts work correctly, but you have to be careful about priority.  Specifically, in the NVIC, lower-numbered priorities are higher.  Also, there’s an intermediate priority level (configMAX_SYSCALL_INTERRUPT_PRIORITY) above which you can’t call FreeRTOS routines.  There’s a lot more information on the FreeRTOS website, but it’s slightly difficult to find.  (It would be nice if there was a FAQ about it, or a more-prominent link in a section talking about Cortex procs.)  Here’s where to start reading: /fr-content-src/uploads/2019/07/index.html?http://www.freertos.org/portcortexgcc.html Near the bottom of the main frame, under the heading "RTOS Port specific configuration"

xSemaphoreTake gets blocked

I’m not sure what you mean by "custom interrupts have to be avoided".  Its fine to have any interrupts you want provided there are no resource conflicts. Was your interrupt using the FreeRTOS API?  If so then ensure only API functions that end in FromISR were being used and that the interrupt priority was less than or equal to configMAX_SYSCALL_INTERRUPT_PRIORITY (remembering that low number mean high priorities on the Cortex M3). Regards.

xSemaphoreTake gets blocked

Thanks both for your remarks. I’m quite new in FreeRTOS and have still a lot to learn… and I’m really happy to know that I can use interrupts together with RfeeRTOS. My custom interrupt (the one currently triggering the ADC reads) has now the lowest priority (255) but it still makes the system crash. I’m now thinking that maybe the problem is in the timer used to trigger these ADC conversions periodically. I did verify that this timer was not used anywhere by the Os but maybe I should do a second check (I’m not the author of the FreeRTOS port) More news tomorrow… Daniel.

xSemaphoreTake gets blocked

My application no longer uses a timer to trigger ADC conversions… and the problem persists.

xSemaphoreTake gets blocked

I forgot to say that the interrupt is not calling any function from the FreeRTOS API. It just reads the ADC values.

xSemaphoreTake gets blocked

Can you post the interrupt code?

xSemaphoreTake gets blocked

Of course! TaskIO.c runs in a separate task, all the routines regarding the IO management. setup_analog_inps() is the function that sets up the ADC sequencer (sequencer 0) and programs Timer1 to trigger the sequencer every 0.1 sec: static void setup_analog_inps(void) {     SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC);        // Enable ADC     SysCtlPeripheralEnable(SYSCTL_PERIPH_TIMER1);    // Enable Timer 1     ADCSequenceDisable(ADC_BASE, 1);                        // Disable ADC sequencer 1     // Configure the ADC to sample when the timer expires     // After sampling, the ADC will interrupt the processor     ADCSequenceConfigure(ADC_BASE, 0, ADC_TRIGGER_TIMER, 255);     ADCSequenceStepConfigure(ADC_BASE, 0, 0,ADC_CTL_CH0 );     ADCSequenceStepConfigure(ADC_BASE, 0, 1,ADC_CTL_CH1 );     ADCSequenceStepConfigure(ADC_BASE, 0, 2,ADC_CTL_CH2 );     ADCSequenceStepConfigure(ADC_BASE, 0, 3,ADC_CTL_CH3 | ADC_CTL_IE | ADC_CTL_END);     ADCSequenceEnable(ADC_BASE, 0);     ADCIntEnable(ADC_BASE, 0);     IntEnable(INT_ADC0);     // Configure Timer 1 to generate triggers to the ADC     TimerConfigure(TIMER1_BASE, TIMER_CFG_32_BIT_PER);     TimerLoadSet(TIMER1_BASE, TIMER_A, SysCtlClockGet()/10);        // Trigger every 0.1 secs     TimerControlStall(TIMER1_BASE, TIMER_A, true);     TimerControlTrigger(TIMER1_BASE, TIMER_A, true);     TimerEnable(TIMER1_BASE, TIMER_A); } ADCIntHandler is a callback function called whenever the ADC Sequencer 0 reads new analog data (once every 0.1 sec) void ADCIntHandler(void) {     unsigned long ulData[8];     unsigned long ulmVolt;     unsigned long ulValue;     BYTE bState;     int i;     // Clear the ADC interrupt.     ADCIntClear(ADC_BASE, 0);     // Read the data from the ADC.     ADCSequenceDataGet(ADC_BASE, 0, ulData);     // For every analog input     for(i=0 ; i<NBOF_INPANA ; i++)     {         // Get ADC value in voltage (mV) format         ulmVolt = (ADC_VOLT_RANGE * 1000 * ulData[i]) / 1024;    // Milivolts         // Apply factor and offset for each ADC endpoint         ulValue = ulmVolt * aEndpoint[0].factor + aEndpoint[0].offset;         // Set state         if (ulValue < 10)             bState = 0;         else             bState = 1;         epUpdateValue(i, ‘a’, ulValue, bState);            // Update value in the array of binary endpoints     } } Apart from here, there is no other place where a timer or interrupt is set. Thanks again, Daniel.