Beispiel #1
0
/**
 * Execute the callback of a timer.
 *
 * @param expiredTimer pointer on the timer
 *
 * WARNING: expiredTimer MUST NOT be null (rem: static function )
 */
static void execute_callback(T_TIMER_LIST_ELT *expiredTimer)
{
#ifdef __DEBUG_OS_ABSTRACTION_TIMER
	_log(
		"\nINFO : execute_callback : executing callback of timer 0x%x  (now = %u - expiration = %u)",
		(uint32_t)expiredTimer,
		get_uptime_ms(), expiredTimer->desc.expiration);
#endif
	int flags = irq_lock();

	/* if the timer was not stopped by its own callback */
	if (E_TIMER_RUNNING == expiredTimer->desc.status) {
		remove_timer(expiredTimer);
		/* add it again if repeat flag was on */
		if (expiredTimer->desc.repeat) {
			expiredTimer->desc.expiration = get_uptime_ms() +
							expiredTimer->desc.
							delay;
			add_timer(expiredTimer);
		}
	}
	irq_unlock(flags);

	/* call callback back */
	if (NULL != expiredTimer->desc.callback) {
		expiredTimer->desc.callback(expiredTimer->desc.data);
	} else {
#ifdef __DEBUG_OS_ABSTRACTION_TIMER
		_log("\nERROR : execute_callback : timer callback is null ");
#endif
		panic(E_OS_ERR);
	}
}
Beispiel #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;
}
Beispiel #3
0
/**
 * Main function of the timer task. This function is in charge of
 *    calling the callbacks associated with the timers.
 *
 *    This function is run in a high priority task on microkernel builds.
 *    This function is run in a high priority fiber on nanokernel builds.
 *    It implements an infinite loop that waits for any of the semaphores from
 *    g_TimerSem.
 *    When a semaphore is signaled, this function fetches the pointer to the
 *    associated callback in g_TimerDesc, then calls it.
 *
 * @param dummy1 not used (required by ZEPHYR API)
 * @param dummy2 not used (required by ZEPHYR API) *
 *
 */
void timer_task(int dummy1, int dummy2)
{
	int32_t timeout = UINT32_MAX;
	uint32_t now;

	UNUSED(dummy1);
	UNUSED(dummy2);

	while (1) { /* the Timer task shall never stop */
		/* Before waiting for next timeout, publish it to warn QUARK cpu */
		publish_cpu_timeout(timeout);
		/* block until g_TimerSem is signaled or until the next timeout expires */
#ifdef CONFIG_MICROKERNEL
		(void)task_sem_take(g_TimerSem, CONVERT_MS_TO_TICKS(timeout));
#else
		nano_sem_take(&g_TimerSem, CONVERT_MS_TO_TICKS(timeout));
#endif
		now = get_uptime_ms();
		/* task is unblocked: check for expired timers */
		while (g_CurrentTimerHead &&
		       is_after_expiration(now, &(g_CurrentTimerHead->desc))) {
			execute_callback(g_CurrentTimerHead);
			now = get_uptime_ms();
		}
		/* Compute timeout until the expiration of the next timer */
		if (g_CurrentTimerHead != NULL) {
			/* In micro kernel context, timeout = 0 or timeout < 0 works.
			 * In nano kernel context timeout must be a positive value.
			 */
			timeout = g_CurrentTimerHead->desc.expiration - now;
			if (timeout < 0) panic(E_OS_ERR_OVERFLOW);
		} else {
			timeout = UINT32_MAX;
		}

#ifdef __DEBUG_OS_ABSTRACTION_TIMER
		if (NULL != g_CurrentTimerHead)
			_log(
				"\nINFO : timer_task : now = %u, next timer expires at %u, timeout = %u",
				get_uptime_ms(),
				g_CurrentTimerHead->desc.expiration,
				timeout);
		else
			_log(
				"\nINFO : timer_task : now = %u, no next timer, timeout = OS_WAIT_FOREVER",
				get_uptime_ms());
#endif
	} /* end while(1) */
}
/**
 * Return the next free block of a pool and
 *   mark it as reserved/allocated.
 *
 * @param pool index of the pool in mpool
 *
 * @return allocated buffer or NULL if none is
 *   available
 */
static void *memblock_alloc(uint32_t pool)
{
    uint16_t block;
    uint32_t flags = interrupt_lock();//irq_lock();

    for (block = 0; block < mpool[pool].count; block++) {
        if (((mpool[pool].track)[block / BITS_PER_U32] & 1 <<
             (BITS_PER_U32 - 1 - (block % BITS_PER_U32))) == 0) {
            (mpool[pool].track)[block / BITS_PER_U32] =
                (mpool[pool].track)[block / BITS_PER_U32] |
                (1 << (BITS_PER_U32 - 1 - (block % BITS_PER_U32)));
#ifdef CONFIG_MEMORY_POOLS_BALLOC_STATISTICS
            mpool[pool].cur = mpool[pool].cur + 1;
#ifdef CONFIG_MEMORY_POOLS_BALLOC_TRACK_OWNER
            /* get return address */
            uint32_t ret_a = (uint32_t)__builtin_return_address(0);
            mpool[pool].owners[block] =
                (uint32_t *)(((ret_a & 0xFFFF0U) >> 4) |
                         ((get_uptime_ms() & 0xFFFF0) << 12));
#endif
            if (mpool[pool].cur > mpool[pool].max)
                mpool[pool].max = mpool[pool].cur;
#endif
            interrupt_unlock(flags);//irq_unlock(flags);
            return (void *)(mpool[pool].start +
                    mpool[pool].size * block);
        }
    }
Beispiel #5
0
/**
 * Curie BSP implementation of jerry_port_get_current_time.
 */
double jerry_port_get_current_time (void)
{
  uint32_t uptime_ms = get_uptime_ms ();
  uint32_t epoch_time = uptime_to_epoch (uptime_ms);

  return ((double) epoch_time) * 1000.0;
} /* jerry_port_get_current_time */
Beispiel #6
0
/**
 * Remove a timer from the list of active timers.
 *
 * @param timerToRemove pointer on the timer to remove
 *
 * WARNING: timerToRemove MUST NOT be null (rem: static function )
 *
 */
static void remove_timer(T_TIMER_LIST_ELT *timerToRemove)
{
	T_TIMER_LIST_ELT *removePoint;

#ifdef __DEBUG_OS_ABSTRACTION_TIMER
	_log(
		"\nINFO : remove_timer - start: removing 0x%x to expire at %d (now = %d)",
		(uint32_t)timerToRemove, timerToRemove->desc.expiration,
		get_uptime_ms());
	display_list();
#endif

	if (NULL != g_CurrentTimerHead) {
		removePoint = g_CurrentTimerHead;
		while (NULL != removePoint) {
			if (timerToRemove == removePoint) {
				if (NULL != timerToRemove->next) {
					timerToRemove->next->prev =
						timerToRemove->prev;
				}
				if (NULL != timerToRemove->prev) {
					timerToRemove->prev->next =
						timerToRemove->next;
				}
			}
			removePoint = removePoint->next;
		}

		if (timerToRemove == g_CurrentTimerHead) {
			g_CurrentTimerHead = g_CurrentTimerHead->next;
			if (NULL != g_CurrentTimerHead) {
				g_CurrentTimerHead->prev = NULL;
			}
		}
	} else {
#ifdef __DEBUG_OS_ABSTRACTION_TIMER
		_log("\nERROR : remove_timer : list of active timer is empty ");
#endif
		panic(E_OS_ERR);
	}

	/* clean-up links */
	timerToRemove->prev = NULL;
	timerToRemove->next = NULL;
	timerToRemove->desc.status = E_TIMER_READY;


#ifdef __DEBUG_OS_ABSTRACTION_TIMER
	_log("\nINFO : remove_timer - end ");
	display_list();
#endif
}
Beispiel #7
0
void panic_handler(void)
{
	irq_lock();

	struct arcv2_panic_arch_data *arc_info =
		(struct arcv2_panic_arch_data *)&arcv2_panic_data->arch_data;
	struct panic_data_footer *footer =
		(struct panic_data_footer *)&arcv2_panic_data->footer;

	footer->struct_size = sizeof(struct panic_data_footer) +
			      sizeof(struct arcv2_panic_arch_data);
	// Copy stack to panic RAM location if sp is valid
	if (IN_RANGE(arc_info->sp, ARC_RAM_START_ADDR,
		     ARC_RAM_START_ADDR + ARC_RAM_SIZE * 1024) ||
	    IN_RANGE(arc_info->sp, ARC_DCCM_START_ADDR,
		     ARC_DCCM_START_ADDR + CONFIG_QUARK_SE_ARC_DCCM_SIZE)) {
		uint8_t *stack_dump = (uint8_t *)arc_info -
				      PANIC_ARC_STACK_SIZE;
		// Align sp pointer on 32bits to avoid alignement issues
		memcpy(stack_dump, (uint32_t *)((arc_info->sp + 3) & (~3)),
		       PANIC_ARC_STACK_SIZE);

		footer->struct_size += PANIC_ARC_STACK_SIZE;
	}

	footer->arch = ARC_CORE;
	footer->flags = PANIC_DATA_FLAG_FRAME_VALID |
			PANIC_DATA_FLAG_FRAME_BLE_AVAILABLE;
	footer->magic = PANIC_DATA_MAGIC;
	footer->reserved = 0;
	footer->time = get_uptime_ms();
	memcpy(&footer->build_cksum, (const void *)version_header.hash,
	       sizeof(version_header.hash));
	footer->struct_version = version_header.version;

	if (!is_panic) {
		is_panic = true;
		if (!is_panic_notification) {
			// Notify master core that a panic occured
			panic_notify(0);
		} else {
			// Notify master core that panic notification has been processed
			panic_done();
		}
	}
	// Stop core
	while (1) ;
}
Beispiel #8
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);
}
Beispiel #9
0
/**
 * Insert a timer in the list of active timer,
 *    according to its expiration date.
 *
 * @param newTimer pointer on the timer to insert
 *
 * WARNING: newTimer MUST NOT be null (rem: static function )
 *
 */
static void add_timer(T_TIMER_LIST_ELT *newTimer)
{
	T_TIMER_LIST_ELT *insertionPoint;
	T_TIMER_LIST_ELT *listTail;
	bool found;

#ifdef __DEBUG_OS_ABSTRACTION_TIMER
	_log(
		"\nINFO : add_timer - start: adding 0x%x to expire at %d (now = %d - delay = %d - ticktime = %d)",
		(uint32_t)newTimer, newTimer->desc.expiration,
		get_uptime_ms(), newTimer->desc.delay, sys_clock_us_per_tick);
	display_list();
#endif


	if (NULL == g_CurrentTimerHead) {
		/* there is no active timer, make newTimer the head timer */
		g_CurrentTimerHead = newTimer;
		newTimer->prev = NULL;
		newTimer->next = NULL;
	} else {
		/* find the next timer to expire after newTimer->desc.expiration */
		insertionPoint = g_CurrentTimerHead;
		listTail = g_CurrentTimerHead;
		found = false;
		while ((NULL != insertionPoint) && (false == found)) {
			if (!is_after_expiration(newTimer->desc.expiration,
						 &(insertionPoint->desc))) { /* newTimer is due to expire before insertionPoint */
				if (g_CurrentTimerHead == insertionPoint) { /*  insert newTimer before the head timer  */
					g_CurrentTimerHead->prev = newTimer;
					newTimer->prev = NULL;
					newTimer->next = g_CurrentTimerHead;
					g_CurrentTimerHead = newTimer;
				} else { /* insert newTimer between insertionPoint and insertionPoint->prev */
					newTimer->prev = insertionPoint->prev;
					newTimer->next = insertionPoint;
					insertionPoint->prev = newTimer;
					newTimer->prev->next = newTimer;
				}
				/* done */
				found = true;
			} else { /* newTimer is due to expire after insertionPoint, continue searching */
				listTail = insertionPoint; /* update list head marker = last non null insertionPoint */
				/* move downward */
				insertionPoint = insertionPoint->next;
			}
		}

		if ((false == found) && (NULL != listTail)) {
			/* newTimer is due to expire after all others have expired */
			listTail->next = newTimer;
			newTimer->prev = listTail;
		}
	}

	newTimer->desc.status = E_TIMER_RUNNING;

#ifdef __DEBUG_OS_ABSTRACTION_TIMER
	_log("\nINFO : add_timer - end "); display_list();
	display_list();
#endif
}