Exemple #1
0
/// Create and Initialize a Mutex object.
/// \note API identical to osMutexNew
osMutexId_t svcRtxMutexNew (const osMutexAttr_t *attr) {
  os_mutex_t *mutex;
  uint32_t    attr_bits;
  uint8_t     flags;
  const char *name;

  // Process attributes
  if (attr != NULL) {
    name      = attr->name;
    attr_bits = attr->attr_bits;
    mutex     = attr->cb_mem;
    if (mutex != NULL) {
      if (((uint32_t)mutex & 3U) || (attr->cb_size < sizeof(os_mutex_t))) {
        EvrRtxMutexError(NULL, osRtxErrorInvalidControlBlock);
        return NULL;
      }
    } else {
      if (attr->cb_size != 0U) {
        EvrRtxMutexError(NULL, osRtxErrorInvalidControlBlock);
        return NULL;
      }
    }
  } else {
    name      = NULL;
    attr_bits = 0U;
    mutex     = NULL;
  }

  // Allocate object memory if not provided
  if (mutex == NULL) {
    if (osRtxInfo.mpi.mutex != NULL) {
      mutex = osRtxMemoryPoolAlloc(osRtxInfo.mpi.mutex);
    } else {
      mutex = osRtxMemoryAlloc(osRtxInfo.mem.common, sizeof(os_mutex_t), 1U);
    }
    if (mutex == NULL) {
      EvrRtxMutexError(NULL, osErrorNoMemory);
      return NULL;
    }
    flags = osRtxFlagSystemObject;
  } else {
    flags = 0U;
  }

  // Initialize control block
  mutex->id           = osRtxIdMutex;
  mutex->state        = osRtxObjectActive;
  mutex->flags        = flags;
  mutex->attr         = (uint8_t)attr_bits;
  mutex->name         = name;
  mutex->thread_list  = NULL;
  mutex->owner_thread = NULL;
  mutex->owner_prev   = NULL;
  mutex->owner_next   = NULL;
  mutex->lock         = 0U;

  EvrRtxMutexCreated(mutex);

  return mutex;
}
Exemple #2
0
/// Delete a Mutex object.
osStatus_t osMutexDelete (osMutexId_t mutex_id) {
  EvrRtxMutexDelete(mutex_id);
  if (IS_IRQ_MODE() || IS_IRQ_MASKED()) {
    EvrRtxMutexError(mutex_id, osErrorISR);
    return osErrorISR;
  }
  return __svcMutexDelete(mutex_id);
}
Exemple #3
0
/// Create and Initialize a Mutex object.
osMutexId_t osMutexNew (const osMutexAttr_t *attr) {
  EvrRtxMutexNew(attr);
  if (IS_IRQ_MODE() || IS_IRQ_MASKED()) {
    EvrRtxMutexError(NULL, osErrorISR);
    return NULL;
  }
  return __svcMutexNew(attr);
}
Exemple #4
0
/// Acquire a Mutex or timeout if it is locked.
osStatus_t osMutexAcquire (osMutexId_t mutex_id, uint32_t timeout) {
  EvrRtxMutexAcquire(mutex_id, timeout);
  if (IS_IRQ_MODE() || IS_IRQ_MASKED()) {
    EvrRtxMutexError(mutex_id, osErrorISR);
    return osErrorISR;
  }
  return __svcMutexAcquire(mutex_id, timeout);
}
Exemple #5
0
/// Delete a Mutex object.
osStatus_t osMutexDelete (osMutexId_t mutex_id) {
  osStatus_t status;

  EvrRtxMutexDelete(mutex_id);
  if (IsIrqMode() || IsIrqMasked()) {
    EvrRtxMutexError(mutex_id, (int32_t)osErrorISR);
    status = osErrorISR;
  } else {
    status = __svcMutexDelete(mutex_id);
  }
  return status;
}
Exemple #6
0
/// Acquire a Mutex or timeout if it is locked.
osStatus_t osMutexAcquire (osMutexId_t mutex_id, uint32_t timeout) {
  osStatus_t status;

  EvrRtxMutexAcquire(mutex_id, timeout);
  if (IsIrqMode() || IsIrqMasked()) {
    EvrRtxMutexError(mutex_id, (int32_t)osErrorISR);
    status = osErrorISR;
  } else {
    status = __svcMutexAcquire(mutex_id, timeout);
  }
  return status;
}
Exemple #7
0
/// Create and Initialize a Mutex object.
osMutexId_t osMutexNew (const osMutexAttr_t *attr) {
  osMutexId_t mutex_id;

  EvrRtxMutexNew(attr);
  if (IsIrqMode() || IsIrqMasked()) {
    EvrRtxMutexError(NULL, (int32_t)osErrorISR);
    mutex_id = NULL;
  } else {
    mutex_id = __svcMutexNew(attr);
  }
  return mutex_id;
}
Exemple #8
0
/// Delete a Mutex object.
/// \note API identical to osMutexDelete
osStatus_t svcRtxMutexDelete (osMutexId_t mutex_id) {
  os_mutex_t  *mutex = (os_mutex_t *)mutex_id;
  os_mutex_t  *mutex0;
  os_thread_t *thread;
  int8_t       priority;

  // Check parameters
  if ((mutex == NULL) || (mutex->id != osRtxIdMutex)) {
    EvrRtxMutexError(mutex, osErrorParameter);
    return osErrorParameter;
  }

  // Check object state
  if (mutex->state == osRtxObjectInactive) {
    EvrRtxMutexError(mutex, osErrorResource);
    return osErrorResource;
  }

  // Mark object as inactive
  mutex->state = osRtxObjectInactive;

  // Check if Mutex is locked
  if (mutex->lock != 0U) {

    thread = mutex->owner_thread;

    // Remove Mutex from Thread owner list
    if (mutex->owner_next != NULL) {
      mutex->owner_next->owner_prev = mutex->owner_prev;
    }
    if (mutex->owner_prev != NULL) {
      mutex->owner_prev->owner_next = mutex->owner_next;
    } else {
      thread->mutex_list = mutex->owner_next;
    }

    // Restore owner Thread priority
    if (mutex->attr & osMutexPrioInherit) {
      priority = thread->priority_base;
      mutex0   = thread->mutex_list;
      while (mutex0) {
        // Mutexes owned by running Thread
        if ((mutex0->thread_list != NULL) && (mutex0->thread_list->priority > priority)) {
          // Higher priority Thread is waiting for Mutex
          priority = mutex0->thread_list->priority;
        }
        mutex0 = mutex0->owner_next;
      }
      if (thread->priority != priority) {
        thread->priority = priority;
        osRtxThreadListSort(thread);
      }
    }

    // Unblock waiting threads
    if (mutex->thread_list != NULL) {
      do {
        thread = osRtxThreadListGet((os_object_t*)mutex);
        osRtxThreadWaitExit(thread, (uint32_t)osErrorResource, false);
      } while (mutex->thread_list != NULL);
    }

    osRtxThreadDispatch(NULL);
  }

  // Free object memory
  if (mutex->flags & osRtxFlagSystemObject) {
    if (osRtxInfo.mpi.mutex != NULL) {
      osRtxMemoryPoolFree(osRtxInfo.mpi.mutex, mutex);
    } else {
      osRtxMemoryFree(osRtxInfo.mem.common, mutex);
    }
  }

  EvrRtxMutexDestroyed(mutex);

  return osOK;
}
Exemple #9
0
/// Release a Mutex that was acquired by osMutexAcquire.
/// \note API identical to osMutexRelease
osStatus_t svcRtxMutexRelease (osMutexId_t mutex_id) {
  os_mutex_t  *mutex = (os_mutex_t *)mutex_id;
  os_mutex_t  *mutex0;
  os_thread_t *thread;
  os_thread_t *runnig_thread;
  int8_t       priority;

  runnig_thread = osRtxThreadGetRunning();
  if (runnig_thread == NULL) {
    EvrRtxMutexError(mutex, osRtxErrorKernelNotRunning);
    return osError;
  }

  // Check parameters
  if ((mutex == NULL) || (mutex->id != osRtxIdMutex)) {
    EvrRtxMutexError(mutex, osErrorParameter);
    return osErrorParameter;
  }

  // Check object state
  if (mutex->state == osRtxObjectInactive) {
    EvrRtxMutexError(mutex, osErrorResource);
    return osErrorResource;
  }

  // Check if running Thread is not the owner
  if (mutex->owner_thread != runnig_thread) {
    EvrRtxMutexError(mutex, osRtxErrorMutexNotOwned);
    return osErrorResource;
  }

  // Check if Mutex is not locked
  if (mutex->lock == 0U) {
    EvrRtxMutexError(mutex, osRtxErrorMutexNotLocked);
    return osErrorResource;
  }

  // Decrement Lock counter
  mutex->lock--;
  EvrRtxMutexReleased(mutex, mutex->lock);

  // Check Lock counter
  if (mutex->lock != 0U) {
    return osOK;
  }

  // Remove Mutex from Thread owner list
  if (mutex->owner_next != NULL) {
    mutex->owner_next->owner_prev = mutex->owner_prev;
  }
  if (mutex->owner_prev != NULL) {
    mutex->owner_prev->owner_next = mutex->owner_next;
  } else {
    runnig_thread->mutex_list = mutex->owner_next;
  }

  // Restore running Thread priority
  if (mutex->attr & osMutexPrioInherit) {
    priority = runnig_thread->priority_base;
    mutex0   = runnig_thread->mutex_list;
    while (mutex0) {
      // Mutexes owned by running Thread
      if ((mutex0->thread_list != NULL) && (mutex0->thread_list->priority > priority)) {
        // Higher priority Thread is waiting for Mutex
        priority = mutex0->thread_list->priority;
      }
      mutex0 = mutex0->owner_next;
    }
    runnig_thread->priority = priority;
  }

  // Check if Thread is waiting for a Mutex
  if (mutex->thread_list != NULL) {
    // Wakeup waiting Thread with highest Priority
    thread = osRtxThreadListGet((os_object_t*)mutex);
    osRtxThreadWaitExit(thread, (uint32_t)osOK, false);
    // Thread is the new Mutex owner
    mutex->owner_thread = thread;
    mutex->owner_next   = thread->mutex_list;
    mutex->owner_prev   = NULL;
    thread->mutex_list  = mutex;
    mutex->lock = 1U;
    EvrRtxMutexAcquired(mutex, 1U);
  }

  osRtxThreadDispatch(NULL);

  return osOK;
}
Exemple #10
0
/// Acquire a Mutex or timeout if it is locked.
/// \note API identical to osMutexAcquire
osStatus_t svcRtxMutexAcquire (osMutexId_t mutex_id, uint32_t timeout) {
  os_mutex_t  *mutex = (os_mutex_t *)mutex_id;
  os_thread_t *runnig_thread;

  runnig_thread = osRtxThreadGetRunning();
  if (runnig_thread == NULL) {
    EvrRtxMutexError(mutex, osRtxErrorKernelNotRunning);
    return osError;
  }

  // Check parameters
  if ((mutex == NULL) || (mutex->id != osRtxIdMutex)) {
    EvrRtxMutexError(mutex, osErrorParameter);
    return osErrorParameter;
  }

  // Check object state
  if (mutex->state == osRtxObjectInactive) {
    EvrRtxMutexError(mutex, osErrorResource);
    return osErrorResource;
  }

  // Check if Mutex is not locked
  if (mutex->lock == 0U) {
    // Acquire Mutex
    mutex->owner_thread = runnig_thread;
    mutex->owner_next   = runnig_thread->mutex_list;
    mutex->owner_prev   = NULL;
    if (runnig_thread->mutex_list != NULL) {
        runnig_thread->mutex_list->owner_prev = mutex;
    }
    runnig_thread->mutex_list = mutex;
    mutex->lock = 1U;
    EvrRtxMutexAcquired(mutex, mutex->lock);
    return osOK;
  }

  // Check if Mutex is recursive and running Thread is the owner
  if ((mutex->attr & osMutexRecursive) && (mutex->owner_thread == runnig_thread)) {
    // Increment lock counter
    if (mutex->lock == osRtxMutexLockLimit) {
      EvrRtxMutexError(mutex, osRtxErrorMutexLockLimit);
      return osErrorResource;
    }
    mutex->lock++;
    EvrRtxMutexAcquired(mutex, mutex->lock);
    return osOK;
  }

  // Check if timeout is specified
  if (timeout != 0U) {
    // Check if Priority inheritance protocol is enabled
    if (mutex->attr & osMutexPrioInherit) {
      // Raise priority of owner Thread if lower than priority of running Thread
      if (mutex->owner_thread->priority < runnig_thread->priority) {
        mutex->owner_thread->priority = runnig_thread->priority;
        osRtxThreadListSort(mutex->owner_thread);
      }
    }
    EvrRtxMutexAcquirePending(mutex, timeout);
    // Suspend current Thread
    osRtxThreadListPut((os_object_t*)mutex, runnig_thread);
    osRtxThreadWaitEnter(osRtxThreadWaitingMutex, timeout);
    return osErrorTimeout;
  }

  // Mutex was not acquired
  EvrRtxMutexNotAcquired(mutex);

  return osErrorResource;
}
Exemple #11
0
/// Create and Initialize a Mutex object.
/// \note API identical to osMutexNew
static osMutexId_t svcRtxMutexNew (const osMutexAttr_t *attr) {
  os_mutex_t *mutex;
  uint32_t    attr_bits;
  uint8_t     flags;
  const char *name;

  // Process attributes
  if (attr != NULL) {
    name      = attr->name;
    attr_bits = attr->attr_bits;
    //lint -e{9079} "conversion from pointer to void to pointer to other type" [MISRA Note 6]
    mutex     = attr->cb_mem;
    if (mutex != NULL) {
      //lint -e(923) -e(9078) "cast from pointer to unsigned int" [MISRA Note 7]
      if ((((uint32_t)mutex & 3U) != 0U) || (attr->cb_size < sizeof(os_mutex_t))) {
        EvrRtxMutexError(NULL, osRtxErrorInvalidControlBlock);
        //lint -e{904} "Return statement before end of function" [MISRA Note 1]
        return NULL;
      }
    } else {
      if (attr->cb_size != 0U) {
        EvrRtxMutexError(NULL, osRtxErrorInvalidControlBlock);
        //lint -e{904} "Return statement before end of function" [MISRA Note 1]
        return NULL;
      }
    }
  } else {
    name      = NULL;
    attr_bits = 0U;
    mutex     = NULL;
  }

  // Allocate object memory if not provided
  if (mutex == NULL) {
    if (osRtxInfo.mpi.mutex != NULL) {
      //lint -e{9079} "conversion from pointer to void to pointer to other type" [MISRA Note 5]
      mutex = osRtxMemoryPoolAlloc(osRtxInfo.mpi.mutex);
    } else {
      //lint -e{9079} "conversion from pointer to void to pointer to other type" [MISRA Note 5]
      mutex = osRtxMemoryAlloc(osRtxInfo.mem.common, sizeof(os_mutex_t), 1U);
    }
#if (defined(OS_OBJ_MEM_USAGE) && (OS_OBJ_MEM_USAGE != 0))
    if (mutex != NULL) {
      uint32_t used;
      osRtxMutexMemUsage.cnt_alloc++;
      used = osRtxMutexMemUsage.cnt_alloc - osRtxMutexMemUsage.cnt_free;
      if (osRtxMutexMemUsage.max_used < used) {
        osRtxMutexMemUsage.max_used = used;
      }
    }
#endif
    flags = osRtxFlagSystemObject;
  } else {
    flags = 0U;
  }

  if (mutex != NULL) {
    // Initialize control block
    mutex->id           = osRtxIdMutex;
    mutex->flags        = flags;
    mutex->attr         = (uint8_t)attr_bits;
    mutex->name         = name;
    mutex->thread_list  = NULL;
    mutex->owner_thread = NULL;
    mutex->owner_prev   = NULL;
    mutex->owner_next   = NULL;
    mutex->lock         = 0U;

    EvrRtxMutexCreated(mutex, mutex->name);
  } else {
    EvrRtxMutexError(NULL, (int32_t)osErrorNoMemory);
  }

  return mutex;
}
Exemple #12
0
/// Delete a Mutex object.
/// \note API identical to osMutexDelete
static osStatus_t svcRtxMutexDelete (osMutexId_t mutex_id) {
        os_mutex_t  *mutex = osRtxMutexId(mutex_id);
  const os_mutex_t  *mutex0;
        os_thread_t *thread;
        int8_t       priority;

  // Check parameters
  if ((mutex == NULL) || (mutex->id != osRtxIdMutex)) {
    EvrRtxMutexError(mutex, (int32_t)osErrorParameter);
    //lint -e{904} "Return statement before end of function" [MISRA Note 1]
    return osErrorParameter;
  }

  // Check if Mutex is locked
  if (mutex->lock != 0U) {

    thread = mutex->owner_thread;

    // Remove Mutex from Thread owner list
    if (mutex->owner_next != NULL) {
      mutex->owner_next->owner_prev = mutex->owner_prev;
    }
    if (mutex->owner_prev != NULL) {
      mutex->owner_prev->owner_next = mutex->owner_next;
    } else {
      thread->mutex_list = mutex->owner_next;
    }

    // Restore owner Thread priority
    if ((mutex->attr & osMutexPrioInherit) != 0U) {
      priority = thread->priority_base;
      mutex0   = thread->mutex_list;
      while (mutex0 != NULL) {
        // Mutexes owned by running Thread
        if ((mutex0->thread_list != NULL) && (mutex0->thread_list->priority > priority)) {
          // Higher priority Thread is waiting for Mutex
          priority = mutex0->thread_list->priority;
        }
        mutex0 = mutex0->owner_next;
      }
      if (thread->priority != priority) {
        thread->priority = priority;
        osRtxThreadListSort(thread);
      }
    }

    // Unblock waiting threads
    if (mutex->thread_list != NULL) {
      do {
        thread = osRtxThreadListGet(osRtxObject(mutex));
        osRtxThreadWaitExit(thread, (uint32_t)osErrorResource, FALSE);
      } while (mutex->thread_list != NULL);
    }

    osRtxThreadDispatch(NULL);
  }

  // Mark object as invalid
  mutex->id = osRtxIdInvalid;

  // Free object memory
  if ((mutex->flags & osRtxFlagSystemObject) != 0U) {
    if (osRtxInfo.mpi.mutex != NULL) {
      (void)osRtxMemoryPoolFree(osRtxInfo.mpi.mutex, mutex);
    } else {
      (void)osRtxMemoryFree(osRtxInfo.mem.common, mutex);
    }
#if (defined(OS_OBJ_MEM_USAGE) && (OS_OBJ_MEM_USAGE != 0))
    osRtxMutexMemUsage.cnt_free++;
#endif
  }

  EvrRtxMutexDestroyed(mutex);

  return osOK;
}
Exemple #13
0
/// Acquire a Mutex or timeout if it is locked.
/// \note API identical to osMutexAcquire
static osStatus_t svcRtxMutexAcquire (osMutexId_t mutex_id, uint32_t timeout) {
  os_mutex_t  *mutex = osRtxMutexId(mutex_id);
  os_thread_t *runnig_thread;
  osStatus_t   status;

  // Check running thread
  runnig_thread = osRtxThreadGetRunning();
  if (runnig_thread == NULL) {
    EvrRtxMutexError(mutex, osRtxErrorKernelNotRunning);
    //lint -e{904} "Return statement before end of function" [MISRA Note 1]
    return osError;
  }

  // Check parameters
  if ((mutex == NULL) || (mutex->id != osRtxIdMutex)) {
    EvrRtxMutexError(mutex, (int32_t)osErrorParameter);
    //lint -e{904} "Return statement before end of function" [MISRA Note 1]
    return osErrorParameter;
  }

  // Check if Mutex is not locked
  if (mutex->lock == 0U) {
    // Acquire Mutex
    mutex->owner_thread = runnig_thread;
    mutex->owner_next   = runnig_thread->mutex_list;
    mutex->owner_prev   = NULL;
    if (runnig_thread->mutex_list != NULL) {
        runnig_thread->mutex_list->owner_prev = mutex;
    }
    runnig_thread->mutex_list = mutex;
    mutex->lock = 1U;
    EvrRtxMutexAcquired(mutex, mutex->lock);
    status = osOK;
  } else {
    // Check if Mutex is recursive and running Thread is the owner
    if (((mutex->attr & osMutexRecursive) != 0U) && (mutex->owner_thread == runnig_thread)) {
      // Try to increment lock counter
      if (mutex->lock == osRtxMutexLockLimit) {
        EvrRtxMutexError(mutex, osRtxErrorMutexLockLimit);
        status = osErrorResource;
      } else {
        mutex->lock++;
        EvrRtxMutexAcquired(mutex, mutex->lock);
        status = osOK;
      }
    } else {
      // Check if timeout is specified
      if (timeout != 0U) {
        // Check if Priority inheritance protocol is enabled
        if ((mutex->attr & osMutexPrioInherit) != 0U) {
          // Raise priority of owner Thread if lower than priority of running Thread
          if (mutex->owner_thread->priority < runnig_thread->priority) {
            mutex->owner_thread->priority = runnig_thread->priority;
            osRtxThreadListSort(mutex->owner_thread);
          }
        }
        EvrRtxMutexAcquirePending(mutex, timeout);
        // Suspend current Thread
        if (osRtxThreadWaitEnter(osRtxThreadWaitingMutex, timeout)) {
          osRtxThreadListPut(osRtxObject(mutex), runnig_thread);
        } else {
          EvrRtxMutexAcquireTimeout(mutex);
        }
        status = osErrorTimeout;
      } else {
        EvrRtxMutexNotAcquired(mutex);
        status = osErrorResource;
      }
    }
  }

  return status;
}