Example #1
0
/**
 * Signal g_TimerSem to wake-up timer_task.
 *
 */
static void signal_timer_task(void)
{
#ifdef   CONFIG_NANOKERNEL
	nano_sem_give(&g_TimerSem);
#else
	T_EXEC_LEVEL execLvl;

	execLvl = _getExecLevel();
	/* call the nanoK service that corresponds to the current execution level */
	switch (execLvl) {
	case E_EXEC_LVL_ISR:
		isr_sem_give(g_TimerSem);
		break;

	case E_EXEC_LVL_FIBER:
		fiber_sem_give(g_TimerSem);
		break;

	case E_EXEC_LVL_TASK:
		task_sem_give(g_TimerSem);
		break;
	default: /* will not do that from unknown context */
		panic(E_OS_ERR_NOT_SUPPORTED);
		break;
	}
#endif
}
Example #2
0
/**
 * Delete a queue.
 *
 * Free a whole queue.
 * @param queue - The queue to free.
 */
void queue_delete(T_QUEUE queue, OS_ERR_TYPE* err)
{
    OS_ERR_TYPE _err;
    queue_impl_t * q = (queue_impl_t*) queue;
    T_EXEC_LEVEL execLvl = _getExecLevel();
    uint32_t data;
    T_QUEUE_MESSAGE p_msg = &data;

    /* check execution level */
    if ((E_EXEC_LVL_FIBER == execLvl) || (E_EXEC_LVL_TASK == execLvl))
    {
        lock_pool();
        if (queue_used(q) && q->sema != NULL)
        {

            /* first empty the queue before to delete it to free all the elements */
            do{
                queue_get_message(q, &p_msg, OS_NO_WAIT, &_err);
            }while(_err == E_OS_OK);

            if(_err == E_OS_ERR_EMPTY)
            {
                semaphore_delete(q->sema, &_err);
                q->sema = NULL;
                if( _err == E_OS_OK)
                {
                    queue_free(q);
                    error_management (err, E_OS_OK);
                }
                else
                {
                    panic(E_OS_ERR_UNKNOWN);    // Panic because we should never reach this point.
                }
            }
            else
            {
                error_management (err, E_OS_ERR);
            }
        }
        else
        {
            error_management (err, E_OS_ERR);
        }
        unlock_pool();
    }
    else
    {
        error_management (err, E_OS_ERR_NOT_ALLOWED);
    }
    return;
}
Example #3
0
/**
 * Read a message from a queue.
 *
 *     Read and dequeue a message.
 *     This service may panic if err parameter is NULL and:
 *      -# queue parameter is invalid, or
 *      -# message parameter is NULL, or
 *      -# when called from an ISR.
 *
 *     Authorized execution levels:  task, fiber.
 *
 * @param queue : handler on the queue (value returned by queue_create).
 *
 * @param message (out): pointer to read message.
 *
 * @param timeout: maximum number of milliseconds to wait for the message. Special
 *                values OS_NO_WAIT and OS_WAIT_FOREVER may be used.
 *
 * @param err (out): execution status:
 *          -# E_OS_OK : a message was read
 *          -# E_OS_ERR_TIMEOUT: no message was received
 *          -# E_OS_ERR_EMPTY: the queue is empty
 *          -# E_OS_ERR: invalid parameter
 *          -# E_OS_ERR_NOT_ALLOWED: service cannot be executed from ISR context.
 */
void queue_get_message (T_QUEUE queue, T_QUEUE_MESSAGE* message, int timeout, OS_ERR_TYPE* err)
{
    OS_ERR_TYPE _err;
    T_EXEC_LEVEL execLvl = _getExecLevel();
    queue_impl_t * q = (queue_impl_t*) queue;

    /* check input parameters */
    if( (message == NULL) || (!queue_used(q)) || (q->sema==NULL) || (timeout<OS_WAIT_FOREVER) )
    {
        error_management (err, E_OS_ERR);
        return;
    }

    /* check execution level */
    if ((E_EXEC_LVL_FIBER == execLvl) || (E_EXEC_LVL_TASK == execLvl))
    {
        _err = semaphore_take(q->sema, timeout);
        switch(_err){

        case E_OS_OK:
        {
            uint32_t it_mask = interrupt_lock();
            _err = remove_data(q, message);
            interrupt_unlock(it_mask);
            error_management (err, E_OS_OK);
        }
            break;
        case E_OS_ERR_TIMEOUT:
            error_management (err, E_OS_ERR_TIMEOUT);
            break;
        case E_OS_ERR_BUSY:
            if(err){
                //QUEUE EMPTY, is a common use case, do not panic even if err == NULL
                *err = E_OS_ERR_EMPTY;
            }
            break;
        default:
            //unknown error
            panic(E_OS_ERR_UNKNOWN);
        }
    }
    else
    {
        error_management (err, E_OS_ERR_NOT_ALLOWED);
    }

    return;
}
Example #4
0
/**
 * Create a message queue.
 *
 *     Create a message queue.
 *     This service may panic if err parameter is NULL and:
 *     -# no queue is available, or
 *     -# when called from an ISR.
 *
 *     Authorized execution levels:  task, fiber.
 *
 *     As for semaphores and mutexes, queues are picked from a pool of
 *     statically-allocated objects.
 *
 * @param maxSize: maximum number of  messages in the queue.
 *     (Rationale: queues only contain pointer to messages)
 *
 * @param err (out): execution status:
 *          -# E_OS_OK : queue was created
 *          -# E_OS_ERR: all queues from the pool are already being used
 *          -# E_OS_ERR_NOT_ALLOWED: service cannot be executed from ISR context.
 *
 * @return Handler on the created queue.
 *     NULL if all allocated queues are already being used.
 */
T_QUEUE queue_create(uint32_t max_size, OS_ERR_TYPE* err)
{
    queue_impl_t * q = NULL;
    T_EXEC_LEVEL execLvl = _getExecLevel();
    OS_ERR_TYPE _err;


    if(max_size==0 || max_size>QUEUE_ELEMENT_POOL_SIZE)
    {
        error_management (err, E_OS_ERR);
        return NULL;
    }

    /* check execution level */
    if ((E_EXEC_LVL_FIBER == execLvl) || (E_EXEC_LVL_TASK == execLvl))
    {
        /* Block concurrent accesses to the pool of queue_list */
        lock_pool();
        q = queue_alloc();
        unlock_pool();

        if (q != NULL)
        {
           list_init(&q->_list);  // replace the following commented code
           q->current_size = 0;
           q->max_size = max_size;
           q->sema = semaphore_create(0, &_err);
           error_management (err, _err);
        }
        else
        {
            error_management (err, E_OS_ERR);
        }
    }
    else
    {
        error_management (err, E_OS_ERR_NOT_ALLOWED);
    }

    return (T_QUEUE)q;
}