masoandro wrote on Saturday, July 14, 2018:
Hello,
I am using FreeRTOS 7.3 on an ARM processor.
I am trying to create a semaphore mutex to protect some hardware devices, but I am not currently having a whole lot of success as the mutex’s are not holding the state like they should and multiple access to the same hardware device is causing a bus collision.
I declare them
volatile xSemaphoreHandle Sema1;
volatile xSemaphoreHandle Sema2;
And then initialize with
Sema1 = xSemaphoreCreateMutex();
Sema2 = xSemaphoreCreateMutex();
As seen in the example https://www.freertos.org/a00122.html
I then want to check that they have been initialized and I should be able to take the semaphore right away.
int sema_init(void){
if( Sema1 == NULL ){
/* Insufficient FreeRTOS heap to create */
return -1;
} else {
/* Semaphore can now be used */
xSemaphoreTake(Sema1, portMAX_DELAY);
}
if( Sema2 == NULL ){
/* Insufficient FreeRTOS heap to create */
return -1;
} else {
/* Semaphore can now be used */
xSemaphoreTake(Sema1, portMAX_DELAY);
}
}
In my code, I then call an open routine in order to “hold” each device and prevent the other one from carrying out its task on that hardware device.
void device_open(int device){
switch(device){
case device1:
xSemaphoreTake(Sema1, portMAX_DELAY);
break;
case device2:
xSemaphoreTake(Sema2, portMAX_DELAY);
break;
}
}
And the close routine:
void device_close(int device){
switch(device){
case device1:
xSemaphoreGive(Sema1);
break;
case device2:
xSemaphoreGive(Sema2);
break;
}
}
After following this discussion, I thought I could take the mutex multiple times. With this solution, the code crashes immediately on the second take. That is, when I switch on device1
in the device_open()
routine it fails.
However, when I leave out the xSemaphoreTake() in the initialization, the semaphores do not hold the device properly and allow for bus interference!
What is the proper way to implement these mutex semaphores so that device2
cannot initialize until device1
has finished its routine?
Thank you for your time!