Example #1
0
/*!
 * \brief Tests the event component for validity and consistency.
 *
 * \param[out] event_error_ptr Pointer to the lightweight event that has an
 * error if MQX found an error in the lightweight event component (NULL if no error
 * is found).
 * \param[out] td_error_ptr    TD on the lightweight event in error (NULL if no
 * error is found).
 *
 * \return MQX_OK
 * \return MQX_CANNOT_CALL_FUNCTION_FROM_ISR (Function cannot be called from an ISR.)
 * \return MQX_LWEVENT_INVALID (A lightweight event was invalid.)
 * \return code from _queue_test() (Waiting queue for a lightweight event has an error.)
 *
 * \warning Cannot be called from an ISR.
 *
 * \see _lwevent_create
 * \see _lwevent_destroy
 */
_mqx_uint _lwevent_test
(
    void      **event_error_ptr,
    void      **td_error_ptr
)
{
    KERNEL_DATA_STRUCT_PTR  kernel_data;
    LWEVENT_STRUCT_PTR      event_ptr;
    _mqx_uint               result;
    _mqx_uint               queue_size;

    _GET_KERNEL_DATA(kernel_data);

    _KLOGE2(KLOG_lwevent_test, event_error_ptr);

    *td_error_ptr = NULL;
    *event_error_ptr = NULL;

#if MQX_CHECK_ERRORS
    if (kernel_data->IN_ISR)
    {
        _KLOGX2(KLOG_lwevent_test, MQX_CANNOT_CALL_FUNCTION_FROM_ISR);
        return (MQX_CANNOT_CALL_FUNCTION_FROM_ISR);
    }/* Endif */
#endif

    /*
     * It is not considered an error if the lwevent component has not been
     * created yet
     */
    if (kernel_data->LWEVENTS.NEXT == NULL)
    {
        return (MQX_OK);
    } /* Endif */

    result = _queue_test((QUEUE_STRUCT_PTR) &kernel_data->LWEVENTS, event_error_ptr);
    if (result != MQX_OK)
    {
        _KLOGX3(KLOG_lwevent_test, result, *event_error_ptr);
        return (result);
    } /* Endif */

    event_ptr = (LWEVENT_STRUCT_PTR) ((void *) kernel_data->LWEVENTS.NEXT);
    queue_size = _QUEUE_GET_SIZE(&kernel_data->LWEVENTS);
    while (queue_size--)
    {
        if (event_ptr->VALID != LWEVENT_VALID)
        {
            result = MQX_LWEVENT_INVALID;
            break;
        } /* Endif */
        result = _queue_test(&event_ptr->WAITING_TASKS, td_error_ptr);
        if (result != MQX_OK)
        {
            break;
        } /* Endif */
        event_ptr = (LWEVENT_STRUCT_PTR) (void *) event_ptr->LINK.NEXT;
    } /* Endwhile */

    _int_enable();

    if (result != MQX_OK)
    {
        *event_error_ptr = (void *) event_ptr;
    } /* Endif */
    _KLOGX4(KLOG_lwevent_test, result, *event_error_ptr, *td_error_ptr);
    return (result);

}
Example #2
0
/*!
 * \brief Tests all the periodic queues and their lightweight timers for
 * validity and consistency.
 *
 * \param[out] period_error_ptr Pointer to the first periodic queue that has
 * an error (NULL if no error is found).
 * \param[out] timer_error_ptr  Pointer to the first timer that has an error
 * (NULL if no error is found).
 *
 * \return MQX_OK (No periodic queues have been created or no errors found
 * in any periodic queues or timers.)
 * \return MQX_LWTIMER_INVALID (Period_ptr points to an invalid periodic queue.)
 * \return Error from _queue_test() (A periodic queue or its queue was in error.)
 *
 * \warning Disables and enables interrupts.
 *
 * \see _lwtimer_add_timer_to_queue
 * \see _lwtimer_cancel_period
 * \see _lwtimer_cancel_timer
 * \see _lwtimer_create_periodic_queue
 */
 _mqx_uint _lwtimer_test
(
    pointer _PTR_ period_error_ptr,
    pointer _PTR_ timer_error_ptr
)
{ /* Body */
    KERNEL_DATA_STRUCT_PTR    kernel_data;
    LWTIMER_STRUCT_PTR        timer_ptr;
    LWTIMER_PERIOD_STRUCT_PTR period_ptr;
    _mqx_uint                 result;

    _GET_KERNEL_DATA(kernel_data);

    _KLOGE3(KLOG_lwtimer_test, period_error_ptr, timer_error_ptr);

    *period_error_ptr = NULL;
    *timer_error_ptr = NULL;

    /*
     * It is not considered an error if the lwtimer component has not been
     * created yet
     */
    if (kernel_data->LWTIMERS.NEXT == NULL)
    {
        return (MQX_OK);
    } /* Endif */

    result = _queue_test(&kernel_data->LWTIMERS, period_error_ptr);
    if (result != MQX_OK)
    {
        _KLOGX3(KLOG_lwtimer_test, result, *period_error_ptr);
        return (result);
    } /* Endif */

    _int_disable();
    period_ptr = (pointer) kernel_data->LWTIMERS.NEXT;
    while ((pointer) period_ptr != (pointer) &kernel_data->LWTIMERS)
    {
        if (period_ptr->VALID != LWTIMER_VALID)
        {
            _int_enable();
            *period_error_ptr = period_ptr;
            _KLOGX3(KLOG_lwtimer_test, MQX_LWTIMER_INVALID, period_ptr);
            return (MQX_LWTIMER_INVALID);
        } /* Endif */
        result = _queue_test(&period_ptr->TIMERS, timer_error_ptr);
        if (result != MQX_OK)
        {
            _int_enable();
            *period_error_ptr = period_ptr;
            _KLOGX4(KLOG_lwtimer_test, result, *period_error_ptr, *timer_error_ptr);
            return (result);
        } /* Endif */
        timer_ptr = (pointer) period_ptr->TIMERS.NEXT;
        while (timer_ptr != (pointer) &period_ptr->TIMERS)
        {
            if (timer_ptr->VALID != LWTIMER_VALID)
            {
                *period_error_ptr = period_ptr;
                *timer_error_ptr = timer_ptr;
                _KLOGX4(KLOG_lwtimer_test, MQX_LWTIMER_INVALID, period_ptr,
                                timer_ptr);
                return (MQX_LWTIMER_INVALID);
            } /* Endif */
            timer_ptr = (pointer) timer_ptr->LINK.NEXT;
        } /* Endwhile */
        period_ptr = (pointer) period_ptr->LINK.NEXT;
    } /* Endwhile */

    _int_enable();
    _KLOGX2(KLOG_lwtimer_test, MQX_OK);
    return (MQX_OK);

} /* Endbody */
Example #3
0
/*!
 * \cond DOXYGEN_PRIVATE
 * \private
 *
 * \brief Used by a task to create an instance of a lightweight event.
 *
 * \param[in] event_ptr Pointer representing location of the event.
 * \param[in] flags     Flags for the light weight event.
 * \param[in] user      User mode
 *
 * \return MQX_OK
 * \return MQX_EINVAL (lwevent is already initialized.)
 * \return MQX_LWEVENT_INVALID (In case of user mode, MQX tries to access
 * a lwevent with inappropriate access rights.)
 *
 * \see _lwevent_create
 * \see LWEVENT_STRUCT
 */
_mqx_uint _lwevent_create_internal
(
    LWEVENT_STRUCT_PTR  event_ptr,
    _mqx_uint           flags,
    bool             user
)
{
    KERNEL_DATA_STRUCT_PTR  kernel_data;
    LWEVENT_STRUCT_PTR      event_chk_ptr;

#if MQX_ENABLE_USER_MODE
    if (user && !_psp_mem_check_access_mask((uint32_t)event_ptr,
                                             sizeof(LWEVENT_STRUCT),
                                             MPU_UM_R, MPU_UM_RW) )
    {
        return MQX_LWEVENT_INVALID;
    }
#endif

    _GET_KERNEL_DATA(kernel_data);

    _KLOGE2(KLOG_lwevent_create, event_ptr);

    _QUEUE_INIT(&event_ptr->WAITING_TASKS, 0);
    event_ptr->VALUE = 0;
    event_ptr->FLAGS = flags;

    if (flags & LWEVENT_AUTO_CLEAR)
        event_ptr->AUTO = ~0;
    else
        event_ptr->AUTO = 0;

    _int_disable();

#if MQX_ENABLE_USER_MODE
    if (user)
    {
        if (kernel_data->USR_LWEVENTS.NEXT == NULL)
        {
            /* Initialize the light weight event queue */
            _QUEUE_INIT(&kernel_data->USR_LWEVENTS, 0);
        }
    }
    else
#endif
    {
        if (kernel_data->LWEVENTS.NEXT == NULL)
        {
            /* Initialize the light weight event queue */
            _QUEUE_INIT(&kernel_data->LWEVENTS, 0);
        }
    }

    event_ptr->VALID = LWEVENT_VALID;

#if MQX_CHECK_ERRORS
    /* Check if lwevent is already initialized */
#if MQX_ENABLE_USER_MODE
    if (user)
    {
        event_chk_ptr = (LWEVENT_STRUCT_PTR)((void *)kernel_data->USR_LWEVENTS.NEXT);
        while (event_chk_ptr != (LWEVENT_STRUCT_PTR)((void *)&kernel_data->USR_LWEVENTS))
        {
            if (event_chk_ptr == event_ptr)
            {
                _int_enable();
                _KLOGX2(KLOG_lwevent_create, MQX_EINVAL);
                return(MQX_EINVAL);
            }
            event_chk_ptr = (LWEVENT_STRUCT_PTR)((void *)event_chk_ptr->LINK.NEXT);
        }
    }
    else
#endif
    {
        event_chk_ptr = (LWEVENT_STRUCT_PTR) ((void *) kernel_data->LWEVENTS.NEXT);
        while (event_chk_ptr != (LWEVENT_STRUCT_PTR) ((void *) &kernel_data->LWEVENTS))
        {
            if (event_chk_ptr == event_ptr)
            {
                _int_enable();
                _KLOGX2(KLOG_lwevent_create, MQX_EINVAL);
                return (MQX_EINVAL);
            }
            event_chk_ptr = (LWEVENT_STRUCT_PTR) ((void *) event_chk_ptr->LINK.NEXT);
        }
    }
#endif

#if MQX_ENABLE_USER_MODE
    if (user)
    {
        _QUEUE_ENQUEUE(&kernel_data->USR_LWEVENTS, &event_ptr->LINK);
    }
    else
#endif
    {
        _QUEUE_ENQUEUE(&kernel_data->LWEVENTS, &event_ptr->LINK);
    }

    _int_enable();

    _KLOGX2(KLOG_lwevent_create, MQX_OK);
    return (MQX_OK);
}
Example #4
0
/*!
 * \brief Used by a task to set the specified event bits in an event.
 *
 * \param[in] event_ptr Pointer to the lightweight event to set bits in.
 * \param[in] bit_mask  Bit mask. Each bit represents an event bit to be set.
 *
 * \return MQX_OK
 * \return MQX_LWEVENT_INVALID (Lightweight event was invalid.)
 *
 * \see _lwevent_create
 * \see _lwevent_destroy
 * \see _lwevent_set_auto_clear
 * \see _lwevent_clear
 * \see _lwevent_test
 * \see _lwevent_wait_for
 * \see _lwevent_wait_ticks
 * \see _lwevent_wait_until
 * \see _lwevent_get_signalled
 * \see LWEVENT_STRUCT
 */
_mqx_uint _lwevent_set
(
    LWEVENT_STRUCT_PTR  event_ptr,
    _mqx_uint           bit_mask
)
{
    KERNEL_DATA_STRUCT_PTR kernel_data;
    QUEUE_ELEMENT_STRUCT_PTR q_ptr;
    QUEUE_ELEMENT_STRUCT_PTR next_q_ptr;
    TD_STRUCT_PTR td_ptr;
    _mqx_uint set_bits;

#if MQX_ENABLE_USER_MODE && MQX_ENABLE_USER_STDAPI
    if (MQX_RUN_IN_USER_MODE)
    {
        return _usr_lwevent_set(event_ptr, bit_mask);
    }
#endif

    _GET_KERNEL_DATA(kernel_data);

    _KLOGE3(KLOG_lwevent_set, event_ptr, bit_mask);

    _INT_DISABLE();
#if MQX_CHECK_VALIDITY
    if (event_ptr->VALID != LWEVENT_VALID)
    {
        _int_enable();
        _KLOGX2(KLOG_lwevent_set, MQX_LWEVENT_INVALID);
        return (MQX_LWEVENT_INVALID);
    } /* Endif */
#endif

    set_bits = event_ptr->VALUE | bit_mask;

    if (_QUEUE_GET_SIZE(&event_ptr->WAITING_TASKS))
    {
        /* Schedule waiting task(s) to run if bits ok */

        q_ptr = event_ptr->WAITING_TASKS.NEXT;
        while (q_ptr != (QUEUE_ELEMENT_STRUCT_PTR) ((void *) &event_ptr->WAITING_TASKS))
        {
            td_ptr = (void *) q_ptr;
            _BACKUP_POINTER(td_ptr, TD_STRUCT, AUX_QUEUE);
            next_q_ptr = q_ptr->NEXT;
            if (((td_ptr->FLAGS & TASK_LWEVENT_ALL_BITS_WANTED) && ((td_ptr->LWEVENT_BITS & set_bits)
                            == td_ptr->LWEVENT_BITS)) || ((!(td_ptr->FLAGS & TASK_LWEVENT_ALL_BITS_WANTED))
                            && (td_ptr->LWEVENT_BITS & set_bits)))
            {
                _QUEUE_REMOVE(&event_ptr->WAITING_TASKS, q_ptr);
                _TIME_DEQUEUE(td_ptr, kernel_data);
                td_ptr->INFO = 0;
                _TASK_READY(td_ptr, kernel_data);

                /* store information about which bits caused task to be unblocked */
                td_ptr->LWEVENT_BITS &= set_bits;
                set_bits &= ~(event_ptr->AUTO & td_ptr->LWEVENT_BITS);

            } /* Endif */
            q_ptr = next_q_ptr;
        } /* Endwhile */
    } /* Endif */

    event_ptr->VALUE = set_bits;
    _INT_ENABLE();

    /* May need to let higher priority task run */
    _CHECK_RUN_SCHEDULER();

    _KLOGX2(KLOG_lwevent_set, MQX_OK);
    return (MQX_OK);

}
Example #5
0
_mqx_uint _watchdog_create_component
   (
      /* [IN] the vector upon which timer interrupts on */
      _mqx_uint        timer_interrupt_vector,
      
      /* [IN] the function to call when a watchdog timer expires */
      void (_CODE_PTR_ error_function)(pointer td_ptr)
   )
{ /* Body */
   KERNEL_DATA_STRUCT_PTR        kernel_data;
   WATCHDOG_COMPONENT_STRUCT_PTR watchdog_component_ptr;
   pointer                       interrupt_data;

   _GET_KERNEL_DATA(kernel_data);
   
   _KLOGE3(KLOG_watchdog_create_component, timer_interrupt_vector, error_function);

#if MQX_CHECK_ERRORS
   if (kernel_data->IN_ISR) {
      _KLOGX2(KLOG_watchdog_create_component, MQX_CANNOT_CALL_FUNCTION_FROM_ISR);
      return(MQX_CANNOT_CALL_FUNCTION_FROM_ISR);
   } /* Endif */
#endif

   _lwsem_wait((LWSEM_STRUCT_PTR)(&kernel_data->COMPONENT_CREATE_LWSEM));
   if (kernel_data->KERNEL_COMPONENTS[KERNEL_WATCHDOG] != NULL) {
      _lwsem_post((LWSEM_STRUCT_PTR)(&kernel_data->COMPONENT_CREATE_LWSEM));
      _KLOGX2(KLOG_watchdog_create_component, MQX_OK);
      return(MQX_OK);
   } /* Endif */

#if MQX_CHECK_ERRORS
   if (!error_function) {
      _lwsem_post((LWSEM_STRUCT_PTR)(&kernel_data->COMPONENT_CREATE_LWSEM));
      _KLOGX2(KLOG_watchdog_create_component, WATCHDOG_INVALID_ERROR_FUNCTION);
      return(WATCHDOG_INVALID_ERROR_FUNCTION);
   } /* Endif */
   if ((timer_interrupt_vector < kernel_data->FIRST_USER_ISR_VECTOR) ||
       (timer_interrupt_vector > kernel_data->LAST_USER_ISR_VECTOR))
   {
      _lwsem_post((LWSEM_STRUCT_PTR)(&kernel_data->COMPONENT_CREATE_LWSEM));
      _KLOGX2(KLOG_watchdog_create_component, WATCHDOG_INVALID_INTERRUPT_VECTOR);
      return(WATCHDOG_INVALID_INTERRUPT_VECTOR);
   } /* Endif */
#endif
   
   /* Get the watchdog component data structure */
   watchdog_component_ptr = (WATCHDOG_COMPONENT_STRUCT_PTR)
      _mem_alloc_system_zero((_mem_size)sizeof(WATCHDOG_COMPONENT_STRUCT));
#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
   if (watchdog_component_ptr == NULL){
      _lwsem_post((LWSEM_STRUCT_PTR)(&kernel_data->COMPONENT_CREATE_LWSEM));
      _KLOGX2(KLOG_watchdog_create_component, MQX_OUT_OF_MEMORY);
      return(MQX_OUT_OF_MEMORY);
   } /* Endif */
#endif   
   _mem_set_type(watchdog_component_ptr, MEM_TYPE_WATCHDOG_COMPONENT);

   watchdog_component_ptr->ERROR_FUNCTION   =
      (void (_CODE_PTR_)(TD_STRUCT_PTR))error_function;
   watchdog_component_ptr->VALID            = WATCHDOG_VALID;
   watchdog_component_ptr->INTERRUPT_VECTOR = timer_interrupt_vector;

   interrupt_data = _int_get_isr_data(timer_interrupt_vector);
   _INT_DISABLE();
   watchdog_component_ptr->TIMER_INTERRUPT_HANDLER = _int_install_isr(
      timer_interrupt_vector, _watchdog_isr, interrupt_data);
#if MQX_CHECK_ERRORS
   if (!watchdog_component_ptr->TIMER_INTERRUPT_HANDLER) {
      _int_enable();
      _lwsem_post((LWSEM_STRUCT_PTR)(&kernel_data->COMPONENT_CREATE_LWSEM));
      _mem_free(watchdog_component_ptr);
      _KLOGX2(KLOG_watchdog_create_component, WATCHDOG_INVALID_INTERRUPT_VECTOR);
      return(WATCHDOG_INVALID_INTERRUPT_VECTOR);
   } /* Endif */
#endif

   kernel_data->KERNEL_COMPONENTS[KERNEL_WATCHDOG] = watchdog_component_ptr;
#if MQX_TASK_DESTRUCTION
   kernel_data->COMPONENT_CLEANUP[KERNEL_WATCHDOG] = _watchdog_cleanup;
#endif
   _INT_ENABLE();
   _lwsem_post((LWSEM_STRUCT_PTR)(&kernel_data->COMPONENT_CREATE_LWSEM));

   _KLOGX2(KLOG_watchdog_create_component, MQX_OK);

   return(MQX_OK);

} /* Endbody */
Example #6
0
/*!
 * \cond DOXYGEN_PRIVATE
 * \private
 *
 * \brief Used by a task to destroy an instance of a lightweight event.
 *
 * \param[in] event_ptr Pointer to the lightweight event to be deinitialized.
 * \param[in] user      User mode
 *
 * \return MQX_OK
 * \return MQX_LWEVENT_INVALID (Lightweight event was not valid.)
 * \return MQX_CANNOT_CALL_FUNCTION_FROM_ISR (Function cannot be called from an ISR.)
 *
 * \see _lwevent_destroy
 * \see LWEVENT_STRUCT
 */
_mqx_uint _lwevent_destroy_internal
(
    LWEVENT_STRUCT_PTR  event_ptr,
    bool             user
)
{
    KERNEL_DATA_STRUCT_PTR kernel_data;
#if MQX_COMPONENT_DESTRUCTION
    TD_STRUCT_PTR td_ptr;
#endif

#if MQX_ENABLE_USER_MODE
    if (user && !_psp_mem_check_access_mask((uint32_t)event_ptr,
                                            sizeof(LWEVENT_STRUCT),
                                            MPU_UM_R, MPU_UM_RW))
    {
        return MQX_LWEVENT_INVALID;
    }
#endif
    _GET_KERNEL_DATA(kernel_data);

   /* Avoid warning for kernel_data in release targets combinated with lite configuration */
    (void)kernel_data;
    _KLOGE2(KLOG_lwevent_destroy, event_ptr);

#if MQX_COMPONENT_DESTRUCTION

#if MQX_CHECK_ERRORS
    if (kernel_data->IN_ISR)
    {
        _KLOGX2(KLOG_lwevent_destroy, MQX_CANNOT_CALL_FUNCTION_FROM_ISR);
        return (MQX_CANNOT_CALL_FUNCTION_FROM_ISR);
    } /* Endif */
#endif

    _int_disable();
#if MQX_CHECK_VALIDITY
    if (event_ptr->VALID != LWEVENT_VALID)
    {
        _int_enable();
        _KLOGX2(KLOG_lwevent_destroy, MQX_LWEVENT_INVALID);
        return (MQX_LWEVENT_INVALID);
    } /* Endif */
#endif

    /* Effectively stop all access to the event */
    event_ptr->VALID = 0;
    while (_QUEUE_GET_SIZE(&event_ptr->WAITING_TASKS))
    {
        _QUEUE_DEQUEUE(&event_ptr->WAITING_TASKS, td_ptr);
        _BACKUP_POINTER(td_ptr, TD_STRUCT, AUX_QUEUE);
        _TIME_DEQUEUE(td_ptr, kernel_data);
        _TASK_READY(td_ptr, kernel_data);
    } /* Endwhile */

    /* remove event from kernel LWEVENTS queue */
#if MQX_ENABLE_USER_MODE
    if (user)
    {
        _QUEUE_REMOVE(&kernel_data->USR_LWEVENTS, event_ptr);
    }
    else
#endif
    {
        _QUEUE_REMOVE(&kernel_data->LWEVENTS, event_ptr);
    }

    _int_enable();

    /* May need to let higher priority task run */
    _CHECK_RUN_SCHEDULER();
#endif

    _KLOGX2(KLOG_lwevent_destroy, MQX_OK);
    return (MQX_OK);
}
Example #7
0
_mqx_uint _lwsem_wait
   (
      /* [IN] the semaphore address */
      LWSEM_STRUCT_PTR sem_ptr
   )
{ /* Body */
    KERNEL_DATA_STRUCT_PTR kernel_data;
    TD_STRUCT_PTR          td_ptr;
   
#if MQX_ENABLE_USER_MODE && MQX_ENABLE_USER_STDAPI
    if (MQX_RUN_IN_USER_MODE) {
        return _usr_lwsem_wait(sem_ptr);
    }
#endif

    _GET_KERNEL_DATA(kernel_data);

    _KLOGE2(KLOG_lwsem_wait, sem_ptr);

#if MQX_CHECK_ERRORS
    if (kernel_data->IN_ISR) {
        _KLOGX2(KLOG_lwsem_wait, MQX_CANNOT_CALL_FUNCTION_FROM_ISR);
        return(MQX_CANNOT_CALL_FUNCTION_FROM_ISR);
    }
#endif
    
#if MQX_CHECK_VALIDITY
    if (sem_ptr->VALID != LWSEM_VALID) {
        _KLOGX2(KLOG_lwsem_wait, MQX_INVALID_LWSEM);
        return(MQX_INVALID_LWSEM);
    }
#endif

    _INT_DISABLE();
    if (sem_ptr->VALUE <= 0) {
        td_ptr = kernel_data->ACTIVE_PTR;
        td_ptr->STATE = LWSEM_BLOCKED;
        td_ptr->INFO  = (_mqx_uint)&sem_ptr->TD_QUEUE;
        _QUEUE_UNLINK(td_ptr);
        _QUEUE_ENQUEUE(&sem_ptr->TD_QUEUE, &td_ptr->AUX_QUEUE);
        _sched_execute_scheduler_internal();  /* Let the other tasks run */
        /* Another task has posted a semaphore, and it has been tranfered to this 
        ** task.
        */
    } else {
        --sem_ptr->VALUE;
    }

//#if MQX_COMPONENT_DESTRUCTION
    /* We must check for component destruction */
    if (sem_ptr->VALID != LWSEM_VALID) {
        _int_enable();
        /* The semaphore has been deleted */
        _KLOGX2(KLOG_lwsem_wait, MQX_INVALID_LWSEM);
        return(MQX_INVALID_LWSEM);
    } /* Endif */
//#endif

    _INT_ENABLE();

    _KLOGX2(KLOG_lwsem_wait, MQX_OK);

    return(MQX_OK);
}
Example #8
0
_mqx_uint _taskq_suspend_task
   (
      /* [IN] the task to suspend */
      _task_id task_id,
      
      /* [IN] the task queue handle */
      pointer  users_task_queue_ptr
   )
{ /* Body */
   register KERNEL_DATA_STRUCT_PTR kernel_data;
   register TASK_QUEUE_STRUCT_PTR  task_queue_ptr = 
      (TASK_QUEUE_STRUCT_PTR)users_task_queue_ptr;
   register TD_STRUCT_PTR          td_ptr;
            boolean                me;

   _GET_KERNEL_DATA(kernel_data);

   _KLOGE3(KLOG_taskq_suspend_task, task_id, users_task_queue_ptr);

   td_ptr = (TD_STRUCT_PTR)_task_get_td(task_id);
   me = (td_ptr == kernel_data->ACTIVE_PTR);

#if MQX_CHECK_ERRORS
   if (td_ptr == NULL) {
      _KLOGX2(KLOG_taskq_suspend_task, MQX_INVALID_TASK_ID);
      return(MQX_INVALID_TASK_ID);
   } /* Endif */
   if (task_queue_ptr == NULL){
      _KLOGX2(KLOG_taskq_suspend_task, MQX_INVALID_PARAMETER);
      return(MQX_INVALID_PARAMETER);
   } /* Endif */
   if (me && kernel_data->IN_ISR) {
      _KLOGX2(KLOG_taskq_suspend_task, MQX_CANNOT_CALL_FUNCTION_FROM_ISR);
      return(MQX_CANNOT_CALL_FUNCTION_FROM_ISR);
   }/* Endif */
#endif

   _INT_DISABLE();

#if MQX_CHECK_VALIDITY
   if (task_queue_ptr->VALID != TASK_QUEUE_VALID) {
      _int_enable();
      _KLOGX2(KLOG_taskq_suspend_task, MQX_INVALID_TASK_QUEUE);
      return(MQX_INVALID_TASK_QUEUE);
   } /* Endif */
#endif

   if (td_ptr->STATE != READY) {
      _INT_ENABLE();
      _KLOGX2(KLOG_taskq_suspend_task, MQX_INVALID_TASK_STATE);
      return(MQX_INVALID_TASK_STATE);
   } /* Endif */

   td_ptr->STATE = TASK_QUEUE_BLOCKED;
   _QUEUE_UNLINK(td_ptr); /* Remove task from ready to run queue */
   td_ptr->INFO = (_mqx_uint)&task_queue_ptr->TD_QUEUE;
   if (task_queue_ptr->POLICY & MQX_TASK_QUEUE_BY_PRIORITY)  {
      _sched_insert_priorityq_internal(&task_queue_ptr->TD_QUEUE, td_ptr);
   } else {
      _QUEUE_ENQUEUE(&task_queue_ptr->TD_QUEUE, td_ptr);
   } /* Endif */

   if (me && (kernel_data->IN_ISR == 0)) {
      _sched_execute_scheduler_internal(); /* Let the other tasks run */
   } /* Endif */

   _INT_ENABLE();

   _KLOGX2(KLOG_taskq_suspend_task, MQX_OK);
   return( MQX_OK );
   
} /* Endbody */
Example #9
0
_mqx_uint _mutex_test
   (
      /* [OUT] - the mutex in error */
      pointer _PTR_ mutex_error_ptr
   )
{ /* Body */
   KERNEL_DATA_STRUCT_PTR     kernel_data;
   MUTEX_COMPONENT_STRUCT_PTR mutex_component_ptr;
   MUTEX_STRUCT_PTR           mutex_ptr;
   _mqx_uint                  result;

   _GET_KERNEL_DATA(kernel_data);

   _KLOGE2(KLOG_mutex_test, mutex_error_ptr);

   *mutex_error_ptr = NULL;

   mutex_component_ptr = (MUTEX_COMPONENT_STRUCT_PTR)
      kernel_data->KERNEL_COMPONENTS[KERNEL_MUTEXES];
   if (mutex_component_ptr == NULL) {
      _KLOGX2(KLOG_mutex_test, MQX_OK);
      return(MQX_OK);
   } /* Endif */

   if (mutex_component_ptr->VALID != MUTEX_VALID) {
      _KLOGX2(KLOG_mutex_test, MQX_INVALID_COMPONENT_BASE);
      return(MQX_INVALID_COMPONENT_BASE);
   } /* Endif */

   _int_disable();

   /* Make sure that the queue of mutexes is ok */
   result = _queue_test(&mutex_component_ptr->MUTEXES, mutex_error_ptr);
   if (result != MQX_OK) {
      _int_enable();
      _KLOGX3(KLOG_mutex_test, result, *mutex_error_ptr);
      return(result);
   } /* Endif */

   mutex_ptr = (MUTEX_STRUCT_PTR)((pointer)mutex_component_ptr->MUTEXES.NEXT);
   while (mutex_ptr != (MUTEX_STRUCT_PTR)
      ((pointer)&mutex_component_ptr->MUTEXES))
   {
      if (mutex_ptr->VALID != MUTEX_VALID) {
         _int_enable();
         *mutex_error_ptr = mutex_ptr;
         _KLOGX3(KLOG_mutex_test, MQX_EINVAL, mutex_ptr);
         return(MQX_EINVAL);
      } /* Endif */
      result = _queue_test(&mutex_ptr->WAITING_TASKS, mutex_error_ptr);
      if (result != MQX_OK) {
         _int_enable();
         *mutex_error_ptr = mutex_ptr;
         _KLOGX3(KLOG_mutex_test, result, mutex_ptr);
         return(result);
      } /* Endif */
      mutex_ptr = (MUTEX_STRUCT_PTR)((pointer)mutex_ptr->LINK.NEXT);
   } /* Endif */
   
   _int_enable();

   _KLOGX2(KLOG_mutex_test, MQX_OK);
   return(MQX_OK);
   
} /* Endbody */
Example #10
0
_mqx_uint _timer_cancel
   (

      /* [IN]  id of the alarm to be cancelled  */
     _timer_id id

   )
{ /* Body */
   KERNEL_DATA_STRUCT_PTR      kernel_data;
   TIMER_COMPONENT_STRUCT_PTR  timer_component_ptr;
   TIMER_ENTRY_STRUCT_PTR      timer_entry_ptr;
   QUEUE_STRUCT_PTR            queue_ptr;

   _GET_KERNEL_DATA(kernel_data);

   _KLOGE2(KLOG_timer_cancel, id);

   timer_component_ptr = kernel_data->KERNEL_COMPONENTS[KERNEL_TIMER];
#if MQX_CHECK_ERRORS
   if (timer_component_ptr == NULL) {
      _KLOGX2(KLOG_timer_cancel, MQX_COMPONENT_DOES_NOT_EXIST);
      return MQX_COMPONENT_DOES_NOT_EXIST; 
   } /* Endif */
#endif
#if MQX_CHECK_VALIDITY
   if (timer_component_ptr->VALID != TIMER_VALID) {
      _KLOGX2(KLOG_timer_cancel, MQX_INVALID_COMPONENT_BASE);
      return MQX_INVALID_COMPONENT_BASE;
   } /* Endif */
#endif
#if MQX_CHECK_ERRORS
   if (id == 0) {
      _KLOGX2(KLOG_timer_cancel, MQX_INVALID_PARAMETER);
      return MQX_INVALID_PARAMETER;
   } /* Endif */

   if (kernel_data->IN_ISR) {
      _KLOGX2(KLOG_timer_cancel, MQX_CANNOT_CALL_FUNCTION_FROM_ISR);
      return MQX_CANNOT_CALL_FUNCTION_FROM_ISR;
   } /* Endif */
#endif

   /* Gain exclusive access to the timer queues */
   /* Start CR 1332 */
   if (kernel_data->ACTIVE_PTR != timer_component_ptr->TIMER_TD_PTR) {
      if (_lwsem_wait(&timer_component_ptr->TIMER_ENTRIES_LWSEM) != MQX_OK) {
         _KLOGX2(KLOG_timer_cancel, MQX_INVALID_LWSEM);
         return(MQX_INVALID_LWSEM);
      } /* Endif */
   } /*Endif */
   timer_entry_ptr = _timer_find_entry_internal(timer_component_ptr, id);
   /* End CR 1332 */

   if ((timer_entry_ptr == NULL) || (timer_entry_ptr->VALID != TIMER_VALID)) {
      if (kernel_data->ACTIVE_PTR != timer_component_ptr->TIMER_TD_PTR) {
         _lwsem_post(&timer_component_ptr->TIMER_ENTRIES_LWSEM);
      } /* Endif */
      _KLOGX2(KLOG_timer_cancel, MQX_INVALID_PARAMETER);
      return MQX_INVALID_PARAMETER;
    } /* Endif */

   if (timer_entry_ptr->MODE == TIMER_ELAPSED_TIME_MODE) {
      queue_ptr = &timer_component_ptr->ELAPSED_TIMER_ENTRIES;
   } else {
      queue_ptr = &timer_component_ptr->KERNEL_TIMER_ENTRIES;
   } /* Endif */

   timer_entry_ptr->VALID = 0;
   timer_entry_ptr->ID = 0;
   if (kernel_data->ACTIVE_PTR != timer_component_ptr->TIMER_TD_PTR) {
      _QUEUE_REMOVE(queue_ptr, timer_entry_ptr);
      _mem_free(timer_entry_ptr);
      _lwsem_post(&timer_component_ptr->TIMER_ENTRIES_LWSEM);
   } /* Endif */

   _KLOGX2(KLOG_timer_cancel, MQX_OK);
   return(MQX_OK);

} /* Endbody */
Example #11
0
_mqx_uint _event_create_component
   (
      /* [IN] the initial number of event */
      _mqx_uint initial_number, 

      /* 
      ** [IN] the number of events to add when
      ** space is no longer available
      */
      _mqx_uint grow_number,

      /* [IN] the maximum number of events allowed */
      _mqx_uint maximum_number 
   )
{ /* Body */
            KERNEL_DATA_STRUCT_PTR     kernel_data;
   register EVENT_COMPONENT_STRUCT_PTR event_component_ptr;
            _mqx_uint                   result;
            
   _GET_KERNEL_DATA(kernel_data);            

   _KLOGE4(KLOG_event_create_component, initial_number, grow_number, maximum_number);

#if MQX_CHECK_ERRORS
   if (kernel_data->IN_ISR) {
      _KLOGX2(KLOG_event_create_component, MQX_CANNOT_CALL_FUNCTION_FROM_ISR);
      return(MQX_CANNOT_CALL_FUNCTION_FROM_ISR);
   } /* Endif */
#endif

   _lwsem_wait((LWSEM_STRUCT_PTR)(&kernel_data->COMPONENT_CREATE_LWSEM));

   event_component_ptr = (EVENT_COMPONENT_STRUCT_PTR)
      kernel_data->KERNEL_COMPONENTS[KERNEL_EVENTS];
   if (event_component_ptr != NULL) {
      _lwsem_post((LWSEM_STRUCT_PTR)(&kernel_data->COMPONENT_CREATE_LWSEM));
      _KLOGX2(KLOG_event_create_component, MQX_OK);
      return(MQX_OK);
   } /* Endif */
   
   event_component_ptr = (EVENT_COMPONENT_STRUCT_PTR)
      _mem_alloc_system_zero((_mem_size)sizeof(EVENT_COMPONENT_STRUCT));
#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
   if (event_component_ptr == NULL) {
      _lwsem_post((LWSEM_STRUCT_PTR)(&kernel_data->COMPONENT_CREATE_LWSEM));
      _KLOGX2(KLOG_event_create_component, MQX_OUT_OF_MEMORY);
      return(MQX_OUT_OF_MEMORY);
   } /* Endif */
#endif
   _mem_set_type(event_component_ptr, MEM_TYPE_EVENT_COMPONENT);

   result = _name_create_handle_internal(&event_component_ptr->NAME_TABLE_HANDLE,
      initial_number, grow_number, maximum_number, initial_number);
#if MQX_CHECK_ERRORS
   if (result != MQX_OK) {
      _lwsem_post((LWSEM_STRUCT_PTR)(&kernel_data->COMPONENT_CREATE_LWSEM));
      _mem_free(event_component_ptr);
      _KLOGX2(KLOG_event_create_component, result);
      return(result);
   } /* Endif */
#endif
   event_component_ptr->VALID             = EVENT_VALID;
   event_component_ptr->GROW_NUMBER       = grow_number;
   if (maximum_number == 0) {
      event_component_ptr->MAXIMUM_NUMBER = MAX_MQX_UINT;
   } else if (maximum_number < initial_number) {
      event_component_ptr->MAXIMUM_NUMBER = initial_number;
   } else {
      event_component_ptr->MAXIMUM_NUMBER = maximum_number;
   } /* Endif */

   kernel_data->KERNEL_COMPONENTS[KERNEL_EVENTS] = event_component_ptr;

#if MQX_TASK_DESTRUCTION
   kernel_data->COMPONENT_CLEANUP[KERNEL_EVENTS] = _event_cleanup;
#endif

   _lwsem_post((LWSEM_STRUCT_PTR)(&kernel_data->COMPONENT_CREATE_LWSEM));
   
   _KLOGX2(KLOG_event_create_component, MQX_OK);
   return(MQX_OK);

} /* Endbody */
Example #12
0
_mqx_uint _lwsem_test
   ( 
      /* [OUT] the light weight semapohre in error */
      pointer _PTR_ lwsem_error_ptr,

      /* [OUT] the td on a light weight semaphore in error */
      pointer _PTR_ td_error_ptr
   )
{ /* Body */
   KERNEL_DATA_STRUCT_PTR kernel_data;
   LWSEM_STRUCT_PTR       sem_ptr;
   _mqx_uint              queue_size;
   _mqx_uint              result;

   _GET_KERNEL_DATA(kernel_data);

   _KLOGE3(KLOG_lwsem_test, lwsem_error_ptr, td_error_ptr);

   *td_error_ptr = NULL;
   *lwsem_error_ptr = NULL;

#if MQX_CHECK_ERRORS
   if (kernel_data->IN_ISR) {
      _KLOGX2(KLOG_lwsem_test, MQX_CANNOT_CALL_FUNCTION_FROM_ISR);
      return(MQX_CANNOT_CALL_FUNCTION_FROM_ISR);
   }/* Endif */
#endif

   _int_disable();

   result = _queue_test((QUEUE_STRUCT_PTR)&kernel_data->LWSEM, lwsem_error_ptr);
   if (result != MQX_OK) {
      _KLOGX3(KLOG_lwsem_test, result, *lwsem_error_ptr);
      return(result);
   } /* Endif */

   sem_ptr    = (LWSEM_STRUCT_PTR)((pointer)kernel_data->LWSEM.NEXT);
   queue_size = _QUEUE_GET_SIZE(&kernel_data->LWSEM);
   while (queue_size--) {
      if (sem_ptr->VALID != LWSEM_VALID) {
         result = MQX_INVALID_LWSEM;
         break;
      } /* Endif */

      result = _queue_test(&sem_ptr->TD_QUEUE, td_error_ptr);
      if (result != MQX_OK) {
         break;
      } /* Endif */
      
      sem_ptr = sem_ptr->NEXT;
   } /* Endwhile */

   _int_enable();

   if (result != MQX_OK) {
      *lwsem_error_ptr = (pointer)sem_ptr;
   } /* Endif */
   _KLOGX4(KLOG_lwsem_test, result, *lwsem_error_ptr, *td_error_ptr);

   return(result);
   
}
Example #13
0
_mqx_uint _event_create_internal
   (
      /* [IN] the string name for the event */
      char _PTR_              name_ptr,

      /* [OUT] where the event pointer is */
      EVENT_STRUCT_PTR _PTR_  event_ptr_ptr
   )
{ /* Body */
            KERNEL_DATA_STRUCT_PTR     kernel_data;
   register EVENT_COMPONENT_STRUCT_PTR event_component_ptr;
   register EVENT_STRUCT_PTR           event_ptr;
            _mqx_uint                   result;
   
   _GET_KERNEL_DATA(kernel_data);                                         

   _KLOGE2(KLOG_event_create, name_ptr);

#if MQX_CHECK_ERRORS
   if (kernel_data->IN_ISR) {
      _KLOGX2(KLOG_event_create, MQX_CANNOT_CALL_FUNCTION_FROM_ISR);
      return(MQX_CANNOT_CALL_FUNCTION_FROM_ISR);
   } /* Endif */
#endif

   event_component_ptr = (EVENT_COMPONENT_STRUCT_PTR)
      kernel_data->KERNEL_COMPONENTS[KERNEL_EVENTS];
   if (event_component_ptr == NULL) {
      result = _event_create_component(EVENT_DEFAULT_INITIAL_NUMBER,
         EVENT_DEFAULT_GROW_NUMBER, EVENT_DEFAULT_MAXIMUM_NUMBER);
      event_component_ptr = (EVENT_COMPONENT_STRUCT_PTR)
         kernel_data->KERNEL_COMPONENTS[KERNEL_EVENTS];
#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
      if (event_component_ptr == NULL){
         _KLOGX2(KLOG_event_create, result);
        return(result);
      } /* Endif */
#endif
   } /* Endif */

#if MQX_CHECK_VALIDITY
   if (event_component_ptr->VALID != EVENT_VALID){
      _KLOGX2(KLOG_event_create, MQX_INVALID_COMPONENT_BASE);
      return(MQX_INVALID_COMPONENT_BASE);
   } /* Endif */
#endif

   event_ptr = (EVENT_STRUCT_PTR)_mem_alloc_system_zero(
      (_mem_size)sizeof(EVENT_STRUCT));
#if MQX_CHECK_MEMORY_ALLOCATION_ERRORS
   if (event_ptr == NULL) {
      _KLOGX2(KLOG_event_create, MQX_OUT_OF_MEMORY);
      return(MQX_OUT_OF_MEMORY);
   } /* Endif */
#endif
   _mem_set_type(event_ptr, MEM_TYPE_EVENT);

   _QUEUE_INIT(&event_ptr->WAITING_TASKS, EVENT_MAX_WAITING_TASKS);

   strncpy(event_ptr->NAME, name_ptr, (_mqx_uint)NAME_MAX_NAME_SIZE-1);
   event_ptr->NAME[NAME_MAX_NAME_SIZE-1] = '\0';
   result = _name_add_internal(event_component_ptr->NAME_TABLE_HANDLE, 
      event_ptr->NAME, (_mqx_uint)event_ptr);
#if MQX_CHECK_ERRORS
   if (result != MQX_OK) {
      _mem_free(event_ptr);
      if (result == NAME_EXISTS) {
         _KLOGX2(KLOG_event_create, EVENT_EXISTS);
         return(EVENT_EXISTS);
      } else if (result == NAME_TABLE_FULL) {
         _KLOGX2(KLOG_event_create, EVENT_TABLE_FULL);
         return(EVENT_TABLE_FULL);
      } /* Endif */
      _KLOGX2(KLOG_event_create, result);
      return(result);
   } /* Endif */
#endif
   event_ptr->VALID = EVENT_VALID;

   *event_ptr_ptr = event_ptr;

   _KLOGX2(KLOG_event_create, result);
   return(result);

} /* Endbody */
Example #14
0
_mqx_uint _lwmsgq_send
   (
      /* Handle to the queue */
      pointer           handle,

      /* location of message to copy in */
      _mqx_max_type_ptr message,

      /* flags for blocking on full, blocking on send */
      _mqx_uint         flags
   )
{/* Body */
   KERNEL_DATA_STRUCT_PTR kernel_data;
   TD_STRUCT_PTR          td_ptr;
   LWMSGQ_STRUCT_PTR      q_ptr = (LWMSGQ_STRUCT_PTR)handle;
   _mqx_uint              i;
   _mqx_max_type_ptr      from_ptr;
   _mqx_max_type_ptr      to_ptr;

#if MQX_ENABLE_USER_MODE && MQX_ENABLE_USER_STDAPI
    if (MQX_RUN_IN_USER_MODE) {
        return _usr_lwmsgq_send(handle, message, flags);
    }
#endif
    
   /* Start CR 1944 */
   _GET_KERNEL_DATA(kernel_data);
   _KLOGE4(KLOG_lwmsgq_send, handle, message, flags);
   /* End CR 1944 */
   
   _int_disable();
#if MQX_CHECK_VALIDITY
   if (q_ptr->VALID != LWMSGQ_VALID){
      _int_enable();
      /* Start CR 1944 */
      _KLOGX2(KLOG_lwmsgq_send, LWMSGQ_INVALID);
      /* End CR 1944 */
      return LWMSGQ_INVALID;
   } /* Endif */
#endif
   if (LWMSGQ_IS_FULL(q_ptr)) {
      if (flags & LWMSGQ_SEND_BLOCK_ON_FULL) {
         td_ptr = kernel_data->ACTIVE_PTR;
         while (LWMSGQ_IS_FULL(q_ptr)) {
            td_ptr->STATE = LWMSGQ_WRITE_BLOCKED;
            td_ptr->INFO  = (_mqx_uint)&q_ptr->WAITING_WRITERS;
            _QUEUE_UNLINK(td_ptr);
            _QUEUE_ENQUEUE(&q_ptr->WAITING_WRITERS, &td_ptr->AUX_QUEUE);
            _sched_execute_scheduler_internal(); /* Let other tasks run */
         } /* Endwhile */
      } else {
         _int_enable();
         /* Start CR 1944 */
         _KLOGX2(KLOG_lwmsgq_send, LWMSGQ_FULL);
         /* End CR 1944 */
         return LWMSGQ_FULL;
      } /* Endif */
   }/* Endif */
   to_ptr = q_ptr->MSG_WRITE_LOC;
   from_ptr = message;
   i = q_ptr->MSG_SIZE+1;
   while (--i) {
      *to_ptr++ = *from_ptr++;
   } /* Endwhile */
   q_ptr->MSG_WRITE_LOC += q_ptr->MSG_SIZE;
   if (q_ptr->MSG_WRITE_LOC >= q_ptr->MSG_END_LOC) {
      q_ptr->MSG_WRITE_LOC = q_ptr->MSG_START_LOC;
   } /* Endif */
   q_ptr->CURRENT_SIZE++;
   if (! _QUEUE_IS_EMPTY(&q_ptr->WAITING_READERS)) {
      _QUEUE_DEQUEUE(&q_ptr->WAITING_READERS, td_ptr);
      _BACKUP_POINTER(td_ptr, TD_STRUCT, AUX_QUEUE);
      _TIME_DEQUEUE(td_ptr, kernel_data);
      td_ptr->INFO = 0;  /* Signal that post is activating the task */
      _TASK_READY(td_ptr, kernel_data);
      if (flags & LWMSGQ_SEND_BLOCK_ON_SEND) {
         _task_block();
      } else {
         _CHECK_RUN_SCHEDULER(); /* Let higher priority task run */
      }/* Endif */
   } else {
      if (flags & LWMSGQ_SEND_BLOCK_ON_SEND) {
         _task_block();
      }/* Endif */
   } /* Endif */
   _int_enable();
   /* Start CR 1944 */
   _KLOGX2(KLOG_lwmsgq_send, MQX_OK);
   /* End CR 1944 */
   return MQX_OK;

}/* Endbody */
Example #15
0
_mqx_uint _sem_post
   (
      /* [IN] -  The semaphore handle returned by _sem_open. */
      pointer users_sem_ptr
   )
{ /* Body */
   KERNEL_DATA_STRUCT_PTR    kernel_data;
   SEM_STRUCT_PTR            sem_ptr;
#if MQX_COMPONENT_DESTRUCTION
   SEM_COMPONENT_STRUCT_PTR  sem_component_ptr;
#endif
   SEM_CONNECTION_STRUCT_PTR new_sem_connection_ptr;
   SEM_CONNECTION_STRUCT_PTR sem_connection_ptr;
   TD_STRUCT_PTR             new_td_ptr;
   boolean                   task_added = FALSE;
   boolean                   destroying_semaphore = FALSE;
            
   _GET_KERNEL_DATA(kernel_data);

   _KLOGE2(KLOG_sem_post, users_sem_ptr);

   sem_connection_ptr = (SEM_CONNECTION_STRUCT_PTR)users_sem_ptr;

#if MQX_CHECK_VALIDITY
   if (sem_connection_ptr->VALID != SEM_VALID) {
      _KLOGX2(KLOG_sem_post, SEM_INVALID_SEMAPHORE_HANDLE);
      return(SEM_INVALID_SEMAPHORE_HANDLE); 
   } /* Endif */
#endif

   sem_ptr = sem_connection_ptr->SEM_PTR;

#if MQX_CHECK_ERRORS
   if (sem_ptr->POLICY & SEM_STRICT) {
      if (kernel_data->IN_ISR) {
         _KLOGX2(KLOG_sem_post, MQX_CANNOT_CALL_FUNCTION_FROM_ISR);
         return(MQX_CANNOT_CALL_FUNCTION_FROM_ISR);
      } /* Endif */

      if (sem_connection_ptr->TD_PTR != kernel_data->ACTIVE_PTR) {
         /* ONLY OPENING task can use the semaphore */
         _KLOGX2(KLOG_sem_post, SEM_INVALID_SEMAPHORE_HANDLE);
         return(SEM_INVALID_SEMAPHORE_HANDLE); 
      } /* Endif */

      if (sem_connection_ptr->POST_STATE == 0) {
         _KLOGX2(KLOG_sem_post, SEM_CANNOT_POST);
         return(SEM_CANNOT_POST);
      } /* Endif */
   } /* Endif */
#endif

   _INT_DISABLE();
   
#if MQX_CHECK_VALIDITY
   if (sem_ptr->VALID != SEM_VALID) {
      _int_enable();
      _KLOGX2(KLOG_sem_post, SEM_INVALID_SEMAPHORE);
      return(SEM_INVALID_SEMAPHORE);
   } /* Endif */
#endif

   if (sem_ptr->POLICY & SEM_STRICT) {
#if MQX_CHECK_ERRORS
      if (sem_ptr->COUNT > sem_ptr->MAX_COUNT) {
         /* Corruption somewhere */
         _int_enable();
         _KLOGX2(KLOG_sem_post, SEM_INVALID_SEMAPHORE_COUNT);
         return(SEM_INVALID_SEMAPHORE_COUNT);
      } /* Endif */
#endif

      --sem_connection_ptr->POST_STATE;
      if (sem_connection_ptr->POST_STATE == 0) {
         _QUEUE_REMOVE(&sem_ptr->OWNING_TASKS, sem_connection_ptr);
      } /* Endif */
   } /* Endif */


   if (_QUEUE_GET_SIZE(&sem_ptr->WAITING_TASKS)) {
      /* Schedule a waiting task to run */

      new_sem_connection_ptr = (SEM_CONNECTION_STRUCT_PTR)
         ((pointer)sem_ptr->WAITING_TASKS.NEXT);
      while (new_sem_connection_ptr != (pointer)&sem_ptr->WAITING_TASKS) {
         new_td_ptr = new_sem_connection_ptr->TD_PTR;
         if ((new_td_ptr->STATE & STATE_MASK) == SEM_BLOCKED) {
            _TIME_DEQUEUE(new_td_ptr, kernel_data);
            _TASK_READY(new_td_ptr, kernel_data);
            new_td_ptr->INFO = SEM_AVAILABLE;
            task_added = TRUE;
            break;
         } /* Endif */
         new_sem_connection_ptr = (SEM_CONNECTION_STRUCT_PTR)
            new_sem_connection_ptr->NEXT;
      } /* Endwhile */

   } /* Endif */
   
   if (!task_added) {

      ++sem_ptr->COUNT;

#if MQX_COMPONENT_DESTRUCTION
     if ( sem_ptr->DELAYED_DESTROY ) {
        if ( ( (sem_ptr->POLICY & SEM_STRICT) &&
               (sem_ptr->COUNT == sem_ptr->MAX_COUNT) ) ||
             ( !(sem_ptr->POLICY & SEM_STRICT) ) ) 
        {
           /* Destroy the semaphore name */
           sem_ptr->VALID = 0;
           destroying_semaphore = TRUE;
        } /* Endif */
      } /* Endif */
#endif
   } /* Endif */

   if (sem_connection_ptr->BOOSTED && (sem_connection_ptr->POST_STATE == 0)) {
      /* This task was boosted by a waiting task */
      _sched_unboost_priority_internal(kernel_data->ACTIVE_PTR, 
         sem_connection_ptr->BOOSTED);
      sem_connection_ptr->BOOSTED = 0;
   } /* Endif */

   _INT_ENABLE();

   /* Let higher priority task run */
   _CHECK_RUN_SCHEDULER();

#if MQX_COMPONENT_DESTRUCTION
   if (destroying_semaphore) {
      sem_component_ptr = (SEM_COMPONENT_STRUCT_PTR)
         kernel_data->KERNEL_COMPONENTS[KERNEL_SEMAPHORES];
      if (sem_component_ptr != NULL) {
         _name_delete_internal(sem_component_ptr->NAME_TABLE_HANDLE,
            sem_ptr->NAME);
      } /* Endif */
      _mem_free(sem_ptr);
   } /* Endif */
#endif

   _KLOGX2(KLOG_sem_post, MQX_OK);
   return(MQX_OK);

} /* Endbody */