Пример #1
0
/// Reset a Message Queue to initial empty state.
/// \note API identical to osMessageQueueReset
osStatus_t svcRtxMessageQueueReset (osMessageQueueId_t mq_id) {
  os_message_queue_t *mq = (os_message_queue_t *)mq_id;
  os_message_t       *msg;
  os_thread_t        *thread;
  uint32_t           *reg;

  // Check parameters
  if ((mq == NULL) || (mq->id != osRtxIdMessageQueue)) {
    EvrRtxMessageQueueError(mq, osErrorParameter);
    return osErrorParameter;
  }

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

  // Remove Messages from Queue
  for (;;) {
    // Get Message from Queue
    msg = MessageQueueGet(mq);
    if (msg == NULL) {
      break;
    }
    MessageQueueRemove(mq, msg);
    EvrRtxMessageQueueRetrieved(mq, NULL);
    // Free memory
    msg->state = osRtxObjectInactive;
    osRtxMemoryPoolFree(&mq->mp_info, msg);
  }

  // Check if Threads are waiting to send Messages
  if ((mq->thread_list != NULL) && (mq->thread_list->state == osRtxThreadWaitingMessagePut)) {
    do {
      // Try to allocate memory
      msg = osRtxMemoryPoolAlloc(&mq->mp_info);
      if (msg != NULL) {
        // Wakeup waiting Thread with highest Priority
        thread = osRtxThreadListGet((os_object_t*)mq);
        osRtxThreadWaitExit(thread, (uint32_t)osOK, false);
        // Copy Message (R2: const void *msg_ptr, R3: uint8_t msg_prio)
        reg = osRtxThreadRegPtr(thread);
        memcpy((uint8_t *)msg + sizeof(os_message_t), (void *)reg[2], mq->msg_size);
        // Store Message into Queue
        msg->id       = osRtxIdMessage;
        msg->state    = osRtxObjectActive;
        msg->flags    = 0U;
        msg->priority = (uint8_t)reg[3];
        MessageQueuePut(mq, msg);
        EvrRtxMessageQueueInserted(mq, (void *)reg[2]);
      }
    } while ((msg != NULL) && (mq->thread_list != NULL));
    osRtxThreadDispatch(NULL);
  }

  EvrRtxMessageQueueResetDone(mq);

  return osOK;
}
Пример #2
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;
}
Пример #3
0
/// Put a Message into a Queue or timeout if Queue is full.
/// \note API identical to osMessageQueuePut
__STATIC_INLINE
osStatus_t isrRtxMessageQueuePut (osMessageQueueId_t mq_id, const void *msg_ptr, uint8_t msg_prio, uint32_t timeout) {
  os_message_queue_t *mq = (os_message_queue_t *)mq_id;
  os_message_t       *msg;
  const void        **ptr;

  // Check parameters
  if ((mq == NULL) || (mq->id != osRtxIdMessageQueue) || (msg_ptr == NULL) || (timeout != 0U)) {
    EvrRtxMessageQueueError(mq, osErrorParameter);
    return osErrorParameter;
  }

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

  // Try to allocate memory
  msg = osRtxMemoryPoolAlloc(&mq->mp_info);
  if (msg != NULL) {
    // Copy Message
    memcpy((uint8_t *)msg + sizeof(os_message_t), msg_ptr, mq->msg_size);
    msg->id       = osRtxIdMessage;
    msg->state    = osRtxObjectActive;
    msg->flags    = 0U;
    msg->priority = msg_prio;
    // Register post ISR processing
     ptr = (void *)&msg->prev;
    *ptr = msg_ptr;
     ptr = (void *)&msg->next;
    *ptr = mq;
    osRtxPostProcess((os_object_t *)msg);
  } else {
    // No memory available
    EvrRtxMessageQueueNotInserted(mq, msg_ptr);
    return osErrorResource;
  }

  EvrRtxMessageQueueInsertPending(mq, msg_ptr);

  return osOK;
}
Пример #4
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;
}
Пример #5
0
/// Get a Message from a Queue or timeout if Queue is empty.
/// \note API identical to osMessageQueueGet
osStatus_t svcRtxMessageQueueGet (osMessageQueueId_t mq_id, void *msg_ptr, uint8_t *msg_prio, uint32_t timeout) {
  os_message_queue_t *mq = (os_message_queue_t *)mq_id;
  os_message_t       *msg;
  os_thread_t        *thread;
  uint32_t           *reg;

  // Check parameters
  if ((mq == NULL) || (mq->id != osRtxIdMessageQueue) || (msg_ptr == NULL)) {
    EvrRtxMessageQueueError(mq, osErrorParameter);
    return osErrorParameter;
  }

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

  // Get Message from Queue
  msg = MessageQueueGet(mq);
  if (msg != NULL) {
    MessageQueueRemove(mq, msg);
    // Copy Message
    memcpy(msg_ptr, (uint8_t *)msg + sizeof(os_message_t), mq->msg_size);
    if (msg_prio != NULL) {
      *msg_prio = msg->priority;
    }
    EvrRtxMessageQueueRetrieved(mq, msg_ptr);
    // Free memory
    msg->state = osRtxObjectInactive;
    osRtxMemoryPoolFree(&mq->mp_info, msg);
  } else {
    // No Message available
    if (timeout != 0U) {
      EvrRtxMessageQueueGetPending(mq, msg_ptr, timeout);
      // Suspend current Thread
      osRtxThreadListPut((os_object_t*)mq, osRtxThreadGetRunning());
      osRtxThreadWaitEnter(osRtxThreadWaitingMessageGet, timeout);
      // Save arguments (R2: void *msg_ptr, R3: uint8_t *msg_prio)
      reg = (uint32_t *)(__get_PSP());
      reg[2] = (uint32_t)msg_ptr;
      reg[3] = (uint32_t)msg_prio;
      return osErrorTimeout;
    } else {
      EvrRtxMessageQueueNotRetrieved(mq, msg_ptr);
      return osErrorResource;
    }
  }

  // Check if Thread is waiting to send a Message
  if ((mq->thread_list != NULL) && (mq->thread_list->state == osRtxThreadWaitingMessagePut)) {
    // Try to allocate memory
    msg = osRtxMemoryPoolAlloc(&mq->mp_info);
    if (msg != NULL) {
      // Wakeup waiting Thread with highest Priority
      thread = osRtxThreadListGet((os_object_t*)mq);
      osRtxThreadWaitExit(thread, (uint32_t)osOK, true);
      // Copy Message (R2: const void *msg_ptr, R3: uint8_t msg_prio)
      reg = osRtxThreadRegPtr(thread);
      memcpy((uint8_t *)msg + sizeof(os_message_t), (void *)reg[2], mq->msg_size);
      // Store Message into Queue
      msg->id       = osRtxIdMessage;
      msg->state    = osRtxObjectActive;
      msg->flags    = 0U;
      msg->priority = (uint8_t)reg[3];
      MessageQueuePut(mq, msg);
      EvrRtxMessageQueueInserted(mq, (void *)reg[2]);
    }
  }

  return osOK;
}
Пример #6
0
/// Create and Initialize a Message Queue object.
/// \note API identical to osMessageQueueNew
osMessageQueueId_t svcRtxMessageQueueNew (uint32_t msg_count, uint32_t msg_size, const osMessageQueueAttr_t *attr) {
  os_message_queue_t *mq;
  void               *mq_mem;
  uint32_t            mq_size;
  uint32_t            block_size;
  uint32_t            size;
  uint8_t             flags;
  const char         *name;

  // Check parameters
  if ((msg_count == 0U) || (msg_size  == 0U)) {
    EvrRtxMessageQueueError(NULL, osErrorParameter);
    return NULL;
  }
  msg_size = (msg_size + 3U) & ~3UL;
  block_size = msg_size + sizeof(os_message_t);
  if ((__CLZ(msg_count) + __CLZ(block_size)) < 32) {
    EvrRtxMessageQueueError(NULL, osErrorParameter);
    return NULL;
  }

  size = msg_count * block_size;

  // Process attributes
  if (attr != NULL) {
    name    = attr->name;
    mq      = attr->cb_mem;
    mq_mem  = attr->mq_mem;
    mq_size = attr->mq_size;
    if (mq != NULL) {
      if (((uint32_t)mq & 3U) || (attr->cb_size < sizeof(os_message_queue_t))) {
        EvrRtxMessageQueueError(NULL, osRtxErrorInvalidControlBlock);
        return NULL;
      }
    } else {
      if (attr->cb_size != 0U) {
        EvrRtxMessageQueueError(NULL, osRtxErrorInvalidControlBlock);
        return NULL;
      }
    }
    if (mq_mem != NULL) {
      if (((uint32_t)mq_mem & 3U) || (mq_size < size)) {
        EvrRtxMessageQueueError(NULL, osRtxErrorInvalidDataMemory);
        return NULL;
      }
    } else {
      if (mq_size != 0U) {
        EvrRtxMessageQueueError(NULL, osRtxErrorInvalidDataMemory);
        return NULL;
      }
    }
  } else {
    name   = NULL;
    mq     = NULL;
    mq_mem = NULL;
  }

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

  // Allocate data memory if not provided
  if (mq_mem == NULL) {
    mq_mem = osRtxMemoryAlloc(osRtxInfo.mem.mq_data, size, 0U);
    if (mq_mem == NULL) {
      EvrRtxMessageQueueError(NULL, osErrorNoMemory);
      if (flags & osRtxFlagSystemObject) {
        if (osRtxInfo.mpi.message_queue != NULL) {
          osRtxMemoryPoolFree(osRtxInfo.mpi.message_queue, mq);
        } else {
          osRtxMemoryFree(osRtxInfo.mem.common, mq);
        }
      }
      return NULL;
    }
    memset(mq_mem, 0, size);
    flags |= osRtxFlagSystemMemory;
  }

  // Initialize control block
  mq->id          = osRtxIdMessageQueue;
  mq->state       = osRtxObjectActive;
  mq->flags       = flags;
  mq->name        = name;
  mq->thread_list = NULL;
  mq->msg_size    = msg_size;
  mq->msg_count   = 0U;
  mq->msg_first   = NULL;
  mq->msg_last    = NULL;
  osRtxMemoryPoolInit(&mq->mp_info, msg_count, block_size, mq_mem);

  // Register post ISR processing function
  osRtxInfo.post_process.message_queue = osRtxMessageQueuePostProcess;

  EvrRtxMessageQueueCreated(mq);

  return mq;
}
Пример #7
0
/// Message Queue post ISR processing.
/// \param[in]  msg             message object.
void osRtxMessageQueuePostProcess (os_message_t *msg) {
  os_message_queue_t *mq;
  os_thread_t        *thread;
  uint32_t           *reg;
  void              **ptr;

  if (msg->state == osRtxObjectInactive) {
    return;
  }

  if (msg->flags != 0U) {
    // Remove Message
    ptr = (void *)((uint8_t *)msg + sizeof(os_message_t));
    mq = *ptr;
    if (mq->state == osRtxObjectInactive) {
      return;
    }
    MessageQueueRemove(mq, msg);
    // Free memory
    msg->state = osRtxObjectInactive;
    osRtxMemoryPoolFree(&mq->mp_info, msg);
    // Check if Thread is waiting to send a Message
    if ((mq->thread_list != NULL) && (mq->thread_list->state == osRtxThreadWaitingMessagePut)) {
      // Try to allocate memory
      msg = osRtxMemoryPoolAlloc(&mq->mp_info);
      if (msg != NULL) {
        // Wakeup waiting Thread with highest Priority
        thread = osRtxThreadListGet((os_object_t*)mq);
        osRtxThreadWaitExit(thread, (uint32_t)osOK, false);
        // Copy Message (R2: const void *msg_ptr, R3: uint8_t msg_prio)
        reg = osRtxThreadRegPtr(thread);
        memcpy((uint8_t *)msg + sizeof(os_message_t), (void *)reg[2], mq->msg_size);
        // Store Message into Queue
        msg->id       = osRtxIdMessage;
        msg->state    = osRtxObjectActive;
        msg->flags    = 0U;
        msg->priority = (uint8_t)reg[3];
        MessageQueuePut(mq, msg);
        EvrRtxMessageQueueInserted(mq, (void *)reg[2]);
      }
    }
  } else {
    // New Message
    mq = (void *)msg->next;
    if (mq->state == osRtxObjectInactive) {
      return;
    }
    // Check if Thread is waiting to receive a Message
    if ((mq->thread_list != NULL) && (mq->thread_list->state == osRtxThreadWaitingMessageGet)) {
      EvrRtxMessageQueueInserted(mq, (void *)msg->prev);
      // Wakeup waiting Thread with highest Priority
      thread = osRtxThreadListGet((os_object_t*)mq);
      osRtxThreadWaitExit(thread, (uint32_t)osOK, false);
      // Copy Message (R2: void *msg_ptr, R3: uint8_t *msg_prio)
      reg = osRtxThreadRegPtr(thread);
      memcpy((void *)reg[2], (uint8_t *)msg + sizeof(os_message_t), mq->msg_size);
      if (reg[3] != 0U) {
        *((uint8_t *)reg[3]) = msg->priority;
      }
      EvrRtxMessageQueueRetrieved(mq, (void *)reg[2]);
      // Free memory
      msg->state = osRtxObjectInactive;
      osRtxMemoryPoolFree(&mq->mp_info, msg);
    } else {
      EvrRtxMessageQueueInserted(mq, (void *)msg->prev);
      MessageQueuePut(mq, msg);
    }
  }
}
Пример #8
0
/// Create and Initialize a timer.
/// \note API identical to osTimerNew
static osTimerId_t svcRtxTimerNew (osTimerFunc_t func, osTimerType_t type, void *argument, const osTimerAttr_t *attr) {
  os_timer_t *timer;
  uint8_t     flags;
  const char *name;

  // Check parameters
  if ((func == NULL) || ((type != osTimerOnce) && (type != osTimerPeriodic))) {
    EvrRtxTimerError(NULL, (int32_t)osErrorParameter);
    //lint -e{904} "Return statement before end of function" [MISRA Note 1]
    return NULL;
  }

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

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

  if (timer != NULL) {
    // Initialize control block
    timer->id         = osRtxIdTimer;
    timer->state      = osRtxTimerStopped;
    timer->flags      = flags;
    timer->type       = (uint8_t)type;
    timer->name       = name;
    timer->prev       = NULL;
    timer->next       = NULL;
    timer->tick       = 0U;
    timer->load       = 0U;
    timer->finfo.func = func;
    timer->finfo.arg  = argument;

    EvrRtxTimerCreated(timer, timer->name);
  } else {
    EvrRtxTimerError(NULL, (int32_t)osErrorNoMemory);
  }

  return timer;
}
Пример #9
0
/// Create and Initialize a Semaphore object.
/// \note API identical to osSemaphoreNew
osSemaphoreId_t svcRtxSemaphoreNew (uint32_t max_count, uint32_t initial_count, const osSemaphoreAttr_t *attr) {
  os_semaphore_t *semaphore;
  uint8_t         flags;
  const char     *name;

  // Check parameters
  if ((max_count == 0U) || (max_count > osRtxSemaphoreTokenLimit) || (initial_count > max_count)) {
    EvrRtxSemaphoreError(NULL, osErrorParameter);
    return NULL;
  }

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

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

  // Initialize control block
  semaphore->id          = osRtxIdSemaphore;
  semaphore->state       = osRtxObjectActive;
  semaphore->flags       = flags;
  semaphore->name        = name;
  semaphore->thread_list = NULL;
  semaphore->tokens      = (uint16_t)initial_count;
  semaphore->max_tokens  = (uint16_t)max_count;

  // Register post ISR processing function
  osRtxInfo.post_process.semaphore = osRtxSemaphorePostProcess;

  EvrRtxSemaphoreCreated(semaphore);

  return semaphore;
}