-1

I have a task that starts up all of the other tasks depending upon a mode byte that is stored in EEPROM. These tasks call the init functions for all of the hardware modules they use. Several tasks use the same hardware, however, with I2C as an example.

These init functions create FreeRTOS objects and I do protect against them from being created more than once, such as in the code snippet below. My concern is that my Startup Task is creating all of these other tasks at once and the OS might be causing a task to call the init function when another task had already called it, particularly in between checking for the NULL value and actually creating the FreeRTOS object. Is this a valid concern for which I should change my design.

   void I2C_Control_Init(void) {
       for(int i2c_control = 0; i2c_control < I2C_CONTROL_NUM; i2c_control++) {
           if (NULL == i2c_control_mutex[i2c_control]) {
               i2c_control_mutex[i2c_control] = xSemaphoreCreateMutex();
               configASSERT(i2c_control_mutex[i2c_control]); // Do not continue with null pointer.
           }
       }
       return;
    }
Bobby
  • 23
  • 4
  • Or create all FreeRTOS objects used by your other tasks later on in the startup task once. Then you could avoid the problem concurrently trying to create these (shared) resources. – HS2 May 30 '22 at 16:09
  • Thanks for the inputs. I have moved them to functions that are called before the tasks are started. – Bobby May 30 '22 at 16:59
  • Please provide enough code so others can better understand or reproduce the problem. – Community May 31 '22 at 04:19
  • "_My concern is ..._" You perfectly describe the problem here. So what's the real question? "_Is this a valid concern?_" Yes, it is. – wovano May 31 '22 at 04:48

1 Answers1

0

The answer to your title question: Yes, FreeRTOS handles "concurrent" creation of OS objects and that's safe. You can write a function that manages this safely.

Your shared code, however, is not thread safe/reentrant with how it stores off and deals with these created objects. As you see yourself, a thread could be iterating your semaphore array, find a NULL, create the semaphore and begin to assign it, then get task switched away and another thread does the same, when it returns your original thread will overwrite what the "interrupting" thread just wrote and you've double claimed an entry and there's a potentially orphan semaphore floating around somewhere, depending on how FreeRTOS is implemented.

How to solve?

The RTOS provides synchronization objects like mutexes, etc. You should use them.

i.e. operating systems 101

Russ Schultz
  • 2,545
  • 20
  • 22
  • Sounds overly complicated. Why not just create the mutex objects before starting all (other) tasks, as already mentioned in the comment? How do you even create the mutex you need to acquire in order to create the `i2c_control_mutex` from the question? – wovano May 31 '22 at 20:58
  • Agreed - that is a simpler method. But there's no doubt the code needs re-written to avoid the race condition on the object creation. – David Jun 13 '22 at 14:36