Ejemplo n.º 1
0
/**
 * Send a message on a queue.
 *
 *     Send / queue a message.
 *     This service may panic if err parameter is NULL and:
 *      -# queue parameter is invalid, or
 *      -# the queue is already full, or
 *
 *     Authorized execution levels:  task, fiber, ISR.
 *
 * @param queue: handler on the queue (value returned by queue_create).
 *
 * @param message (in): pointer to the message to send.
 *
 * @param err (out): execution status:
 *          -# E_OS_OK : a message was read
 *          -# E_OS_ERR_OVERFLOW: the queue is full (message was not posted)
 *          -# E_OS_ERR: invalid parameter
 */
void queue_send_message(T_QUEUE queue, T_QUEUE_MESSAGE message, OS_ERR_TYPE* err )
{
    OS_ERR_TYPE _err;
    queue_impl_t * q = (queue_impl_t*) queue;

    /* check input parameters */
    if( queue_used(q) && q->sema != NULL )
    {
        uint32_t it_mask = interrupt_lock();
        _err = add_data(q, message);
        interrupt_unlock(it_mask);

        if(_err == E_OS_OK)
        {
            semaphore_give(q->sema, &_err);  // signal new message in the queue to the listener.
            error_management (err, E_OS_OK);
        }
        else
        {
            error_management (err, _err);
        }
    }
    else
    {   /* param invalid */
        error_management (err, E_OS_ERR);
    }
    return;
}
Ejemplo n.º 2
0
/**
 * Create  a timer object.
 *     This service may panic if err parameter is null and:
 *         callback parameter is null, or
 *         no timer is available.
 *
 * Authorized execution levels:  task, fiber, ISR
 *
 * @param callback: pointer to the function to be executed.
 * @param privData: pointer to data that shall be passed to the callback
 * @param delay: number of milliseconds between function executions
 * @param repeat: specifies if the timer shall be re-started after each execution of the callback
 * @param startup : specifies if the timer shall be start immediately
 * @param err (out): execution status:
 *         E_OS_OK : callback is programmed
 *         E_OS_ERR: no timer is available, or callback parameter is null
 *
 * @return Handler on the timer, NULL if the service fails (e.g. no available
 *         timer or callback is a null pointer).
 */
T_TIMER timer_create(T_ENTRY_POINT callback, void *privData, uint32_t delay,
		     bool repeat, bool startup,
		     OS_ERR_TYPE *err)
{
	T_TIMER_LIST_ELT *timer = NULL;

	/* check input parameters */
	if ((NULL != callback) && (OS_WAIT_FOREVER != delay)) {
		/* delay should be set to 0 if startup flag is false
		 * otherwise delay should be a positive value if startup flag is true */
		if (((0 < delay) &&
		     (true == startup)) ||
		    ((0 <= delay) && (false == startup))) {
			/* find and reserve a timer resource from g_TimerPool_elements */
			/* rem: timer points to an element from the global g_TimerPool_elements */
			timer = g_TimerPool_alloc();
			if (timer != NULL) {
				/* initialize timer descriptor */
				timer->desc.callback = callback;
				timer->desc.data = privData;
				timer->desc.delay = delay;
				timer->desc.repeat = repeat;
				timer->desc.status = E_TIMER_READY;

				/* insert timer in the list of active timers */
				if (startup) {
					int flags;
					timer->desc.expiration =
						get_uptime_ms() +
						timer->desc.delay;
					flags = irq_lock();
					add_timer(timer);
					irq_unlock(flags);
					if (g_CurrentTimerHead == timer) {
						/* new timer is the next to expire, unblock timer_task to assess the change */
						signal_timer_task();
					}
				}

#ifdef __DEBUG_OS_ABSTRACTION_TIMER
				_log(
					"\nINFO : timer_create : new timer will expire at %u (now = %u ) - addr = 0x%x",
					timer->desc.expiration,
					get_uptime_ms(), (uint32)timer);
#endif
				error_management(err, E_OS_OK);
			} else {
				/* all timers from the pool are already being used */
				error_management(err, E_OS_ERR_NO_MEMORY);
			}
		} else { /* delay and startup parameter are inconsistent */
			error_management(err, E_OS_ERR);
		}
	} else { /* callback == NULL or delay == 0 : at least one parameter is invalid */
		error_management(err, E_OS_ERR);
	}
	return (T_TIMER)timer;
}
Ejemplo n.º 3
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;
}
Ejemplo n.º 4
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;
}
Ejemplo n.º 5
0
/**
 * Delete the timer object.
 *
 * Authorized execution levels:  task, fiber, ISR
 *
 * @param tmr : handler on the timer (value returned by timer_create ).
 * @param err (out): execution status:
 *         E_OS_OK : timer is stopped and callback is disabled
 *         E_OS_ERR: tmr parameter is null, invalid, or timer running
 */
void timer_delete(T_TIMER tmr, OS_ERR_TYPE* err)
{
    T_TIMER_LIST_ELT* timer = (T_TIMER_LIST_ELT*) tmr;
    OS_ERR_TYPE localErr = E_OS_OK;

    if (NULL != timer)
    {
        /* check if timer is running and stop it */
        if (timer->desc.status == E_TIMER_RUNNING)
        {
            timer_stop(timer, err);
        }

#ifdef __DEBUG_OS_ABSTRACTION_TIMER
        _log ("\nINFO : timer_delete : deleting  timer at addr = 0x%x", (uint32) timer);
#endif

        /*  free the timer   */
        g_TimerPool_free(timer);
    }
    else
    { /* tmr is not a timer from g_TimerPool_elements */
        localErr = E_OS_ERR;
    }


    error_management (err, localErr);

}
Ejemplo n.º 6
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;
}
Ejemplo n.º 7
0
/**
 * start the timer.
 *     This service may panic if err parameter is null and:
 *         no timer is available or timer is running .
 *
 * Authorized execution levels:  task, fiber, ISR
 *
 * @param tmr : handler on the timer (value returned by timer_create ).
 * @param err (out): execution status:
 */
void timer_start(T_TIMER tmr, uint32_t delay, OS_ERR_TYPE* err)
{
    T_TIMER_LIST_ELT* timer = (T_TIMER_LIST_ELT*) tmr;
    OS_ERR_TYPE localErr = E_OS_OK;

    /* if timer is created */
    if (NULL != timer)
    {
        if(timer->desc.status == E_TIMER_READY)
        {
            /* if timer parameter are valid */
            if ((NULL != timer->desc.callback) && (0 < delay))
            {
#ifdef __DEBUG_OS_ABSTRACTION_TIMER
                _log ("\nINFO : timer_start : starting  timer ");
#endif
                /* Update expiration time */
                timer->desc.delay = CONVERT_MS_TO_TICKS(delay);
                timer->desc.expiration = _GET_TICK() + timer->desc.delay;
                disable_scheduling();
                /* add the timer */
                add_timer(timer);

                /* new timer is the next to expire, unblock timer_task to assess the change */
                if (g_CurrentTimerHead == timer) {
                     signal_timer_task();
                }
                enable_scheduling();
            }
            else
            {
                 /* timer is not valid */
                 localErr = E_OS_ERR;
            }
        }
        else if(timer->desc.status == E_TIMER_RUNNING)
        {
            localErr = E_OS_ERR_BUSY;
        }
    }
    else
    { /* tmr is not a timer from g_TimerPool_elements */
        localErr = E_OS_ERR;
    }

    error_management(err, localErr);

}
Ejemplo n.º 8
0
/**
 *  Remove the timer in Chained list of timers.
 *     This service may panic if err parameter is null and:
 *         tmr parameter is is null, invalid, or timer is not running.
 *
 * Authorized execution levels:  task, fiber, ISR
 *
 * @param tmr : handler on the timer (value returned by timer_create ).
 * @param err (out): execution status:
 */
void timer_stop(T_TIMER tmr, OS_ERR_TYPE* err)
{
    T_TIMER_LIST_ELT* timer = (T_TIMER_LIST_ELT*)tmr ;
    OS_ERR_TYPE localErr = E_OS_OK;
    bool doSignal = false;

    if ( NULL != timer )
    {
        /* if timer is active */
        if (timer->desc.status == E_TIMER_RUNNING)
        {
#ifdef __DEBUG_OS_ABSTRACTION_TIMER
            _log ("\nINFO : timer_stop : stopping timer at addr = 0x%x", (uint32_t) timer);
#endif
            /* remove the timer */
            disable_scheduling();

            if ( g_CurrentTimerHead == timer )
            {
                doSignal = true ;
            }

            remove_timer(timer);

            if ( doSignal )
            {
                /* the next timer to expire was removed, unblock timer_task to assess the change */
                signal_timer_task();
            }

            enable_scheduling();

        }
        else
        { /* tmr is not running */
            localErr = E_OS_OK;
        }
    }
    else
    { /* tmr is not a timer from g_TimerPool_elements */
        localErr = E_OS_ERR;
    }
    error_management(err, localErr);

}
Ejemplo n.º 9
0
/**
 * start the timer.
 *     This service may panic if err parameter is null and:
 *         no timer is available or timer is running .
 *
 * Authorized execution levels:  task, fiber, ISR
 *
 * @param tmr : handler on the timer (value returned by timer_create ).
 * @param err (out): execution status:
 */
void timer_start(T_TIMER tmr, uint32_t delay, OS_ERR_TYPE *err)
{
	T_TIMER_LIST_ELT *timer = (T_TIMER_LIST_ELT *)tmr;
	OS_ERR_TYPE localErr = E_OS_OK;

	/* if timer is created */
	if (NULL != timer) {
		int flags = irq_lock();
		if (timer->desc.status == E_TIMER_READY) {
			/* if timer parameter are valid */
			if ((NULL != timer->desc.callback) && (0 < delay)) {
#ifdef __DEBUG_OS_ABSTRACTION_TIMER
				_log("\nINFO : timer_start : starting  timer ");
#endif
				/* Update expiration time */
				timer->desc.delay = delay;
				timer->desc.expiration = get_uptime_ms() +
							 timer->desc.delay;
				/* add the timer */
				add_timer(timer);

				irq_unlock(flags);
				/* new timer is the next to expire, unblock timer_task to assess the change */
				if (g_CurrentTimerHead == timer) {
					signal_timer_task();
				}
			} else {
				/* timer is not valid */
				localErr = E_OS_ERR;
			}
		} else if (timer->desc.status == E_TIMER_RUNNING) {
			irq_unlock(flags);
			localErr = E_OS_ERR_BUSY;
			if (err != NULL)
				*err = localErr;
			return;
		}
	} else { /* tmr is not a timer from g_TimerPool_elements */
		localErr = E_OS_ERR;
	}

	error_management(err, localErr);
}