Exemplo n.º 1
0
static void align_to_tick_boundary(void)
{
	uint32_t tick;

	tick = sys_tick_get_32();
	while (sys_tick_get_32() == tick) {
		/* Busy wait to align to tick boundary */
	}
}
Exemplo n.º 2
0
void main(void)
{
	int       status = TC_FAIL;
	uint32_t  start_tick;
	uint32_t  end_tick;

	TC_START("Test Nanokernel Sleep and Wakeup APIs\n");

	test_objects_init();

	test_fiber_id = task_fiber_start(test_fiber_stack, FIBER_STACKSIZE,
					 test_fiber, 0, 0, TEST_FIBER_PRIORITY, 0);
	TC_PRINT("Test fiber started: id = 0x%x\n", test_fiber_id);

	helper_fiber_id = task_fiber_start(helper_fiber_stack, FIBER_STACKSIZE,
						helper_fiber, 0, 0, HELPER_FIBER_PRIORITY, 0);
	TC_PRINT("Helper fiber started: id = 0x%x\n", helper_fiber_id);

	/* Activate test_fiber */
	nano_task_sem_give(&test_fiber_sem);

	/* Wait for test_fiber to activate us */
	nano_task_sem_take(&task_sem, TICKS_UNLIMITED);

	/* Wake the test fiber */
	task_fiber_wakeup(test_fiber_id);

	if (test_failure) {
		goto done_tests;
	}

	TC_PRINT("Testing nanokernel task_sleep()\n");
	align_to_tick_boundary();
	start_tick = sys_tick_get_32();
	task_sleep(ONE_SECOND);
	end_tick = sys_tick_get_32();

	if (end_tick - start_tick != ONE_SECOND) {
		TC_ERROR("task_sleep() slept for %d ticks, not %d\n",
				 end_tick - start_tick, ONE_SECOND);
		goto done_tests;
	}

	status = TC_PASS;

done_tests:
	TC_END_REPORT(status);
}
Exemplo n.º 3
0
int nanoCpuDisableInterruptsTest(disable_interrupt_func disableRtn,
								 enable_interrupt_func enableRtn, int irq)
{
	unsigned long long  count = 0;
	unsigned long long  i = 0;
	int  tick;
	int  tick2;
	int  imask;

	/* Align to a "tick boundary" */
	tick = sys_tick_get_32();
	while (sys_tick_get_32() == tick) {
	}
	tick++;

	while (sys_tick_get_32() == tick) {
		count++;
	}

	/*
	 * Inflate <count> so that when we loop later, many ticks should have
	 * elapsed during the loop.  This later loop will not exactly match the
	 * previous loop, but it should be close enough in structure that when
	 * combined with the inflated count, many ticks will have passed.
	 */

	count <<= 4;

	imask = disableRtn(irq);
	tick = sys_tick_get_32();
	for (i = 0; i < count; i++) {
		sys_tick_get_32();
	}

	tick2 = sys_tick_get_32();

	/*
	 * Re-enable interrupts before returning (for both success and failure
	 * cases).
	 */

	enableRtn(imask);

	if (tick2 != tick) {
		return TC_FAIL;
	}

	/* Now repeat with interrupts unlocked. */
	for (i = 0; i < count; i++) {
		sys_tick_get_32();
	}

	return (tick == sys_tick_get_32()) ? TC_FAIL : TC_PASS;
}
Exemplo n.º 4
0
int nano_cpu_idleTest(void)
{
	int  tick;   /* current tick count */
	int  i;      /* loop variable */

	/* Align to a "tick boundary". */
	tick = sys_tick_get_32();
	while (tick == sys_tick_get_32()) {
	}
	tick = sys_tick_get_32();

	for (i = 0; i < 5; i++) {     /* Repeat the test five times */
		nano_cpu_idle();
		tick++;
		if (sys_tick_get_32() != tick) {
			return TC_FAIL;
		}
	}

	return TC_PASS;
}
void busy_task_entry(void)
{
	int ticks_when_awake;
	int i;

	while (1) {
		/*
		 * go to sleep for 1000 ticks allowing the system entering to sleep
		 * mode if required.
		 */
		is_busy_task_awake = 0;
		SLEEP(1000);
		ticks_when_awake = sys_tick_get_32();

		/*
		 * keep the cpu busy for 1000 ticks preventing the system entering
		 * to sleep mode.
		 */
		is_busy_task_awake = 1;
		while (sys_tick_get_32() - ticks_when_awake < 1000) {
			i++;
		}
	}
}
Exemplo n.º 6
0
static void test_fiber(int arg1, int arg2)
{
	uint32_t start_tick;
	uint32_t end_tick;

	nano_fiber_sem_take(&test_fiber_sem, TICKS_UNLIMITED);

	TC_PRINT("Testing normal expiration of fiber_sleep()\n");
	align_to_tick_boundary();

	start_tick = sys_tick_get_32();
	fiber_sleep(ONE_SECOND);
	end_tick = sys_tick_get_32();

	if (end_tick != start_tick + ONE_SECOND) {
		TC_ERROR(" *** fiber_sleep() slept for %d ticks not %d.",
				 end_tick - start_tick, ONE_SECOND);

		return;
	}

	TC_PRINT("Testing fiber_sleep() + fiber_fiber_wakeup()\n");
	nano_fiber_sem_give(&helper_fiber_sem);   /* Activate helper fiber */
	align_to_tick_boundary();

	start_tick = sys_tick_get_32();
	fiber_sleep(ONE_SECOND);
	end_tick = sys_tick_get_32();

	if (end_tick > start_tick) {
		TC_ERROR(" *** fiber_fiber_wakeup() took too long (%d ticks)\n",
				 end_tick - start_tick);
		return;
	}

	TC_PRINT("Testing fiber_sleep() + isr_fiber_wakeup()\n");
	nano_fiber_sem_give(&helper_fiber_sem);   /* Activate helper fiber */
	align_to_tick_boundary();

	start_tick = sys_tick_get_32();
	fiber_sleep(ONE_SECOND);
	end_tick = sys_tick_get_32();

	if (end_tick > start_tick) {
		TC_ERROR(" *** isr_fiber_wakeup() took too long (%d ticks)\n",
				 end_tick - start_tick);
		return;
	}

	TC_PRINT("Testing fiber_sleep() + task_fiber_wakeup()\n");
	nano_task_sem_give(&task_sem);    /* Activate task */
	align_to_tick_boundary();

	start_tick = sys_tick_get_32();
	fiber_sleep(ONE_SECOND);           /* Task will execute */
	end_tick = sys_tick_get_32();

	if (end_tick > start_tick) {
		TC_ERROR(" *** task_fiber_wakeup() took too long (%d ticks)\n",
				 end_tick - start_tick);
		return;
	}

	test_failure = false;
}
Exemplo n.º 7
0
/**
 * Return the current tick converted in microseconds.
 *
 * Authorized execution levels:  task, fiber
 *
 * ZEPHYR does not provide an API to read a high-precision timer, that
 * returns a 64-bits value.
 * The tick is read as a 32-bits value, then casted to 64-bits.
 *
 * @warning: the return value is false in interrupt context.
 *
 * @return current tick converted in microseconds
 */
uint64_t get_time_us(void)
{
	return (uint64_t)CONVERT_TICKS_TO_US(sys_tick_get_32());
}
Exemplo n.º 8
0
/**
 * Return the current tick converted in milliseconds.
 *
 * Authorized execution levels:  task, fiber
 *
 * @warning: the return value is false in interrupt context.
 *
 * @return current tick converted in milliseconds
 */
uint32_t get_time_ms(void)
{
	return (uint32_t)CONVERT_TICKS_TO_MS(sys_tick_get_32());
}
Exemplo n.º 9
0
void button_pressed(struct device *gpiob,
		    struct gpio_callback *cb, uint32_t pins)
{
	PRINT("Button pressed at %d\n", sys_tick_get_32());
}
/**
 * @brief Summary data printer fiber
 *
 * @details Print the summary data of the context switch events
 * and the total dropped event ocurred.
 *
 * @return No return value.
 */
void summary_data_printer(void)
{
	int i;

	while (1) {
		/* print task data */
		PRINTF("\x1b[1;32HFork manager task");
		if (forks_available) {
			PRINTF("\x1b[2;32HForks : free to use");
		} else {
			PRINTF("\x1b[2;32HForks : all taken  ");
		}

#ifndef CONFIG_NANOKERNEL
		/* Due to fiber are not pre-emptive, the busy_task_entry thread won't
		 * run as a fiber in nanokernel-only system, because it would affect
		 * the visualization of the sample and the collection of the data
		 * while running busy.
		 */
		PRINTF("\x1b[4;32HWorker task");
		if (is_busy_task_awake) {
			PRINTF("\x1b[5;32HState : BUSY");
			PRINTF("\x1b[6;32H(Prevent the system going idle)");
		} else {
			PRINTF("\x1b[5;32HState : IDLE");
			PRINTF("\x1b[6;32H                               ");
		}
#endif

		/* print general data */
		PRINTF("\x1b[8;1HGENERAL DATA");
		PRINTF("\x1b[9;1H------------");

		PRINTF("\x1b[10;1HSystem tick count : %d    ", sys_tick_get_32());

		/* print dropped event counter */
		PRINTF("\x1b[11;1HDropped events #  : %d   ", total_dropped_counter);

		/* Print context switch event data */
		PRINTF("\x1b[13;1HCONTEXT SWITCH EVENT DATA");
		PRINTF("\x1b[14;1H-------------------------");
		PRINTF("\x1b[15;1HThread ID   Switches");
		for (i = 0; i < MAX_BUFFER_CONTEXT_DATA; i++) {
			if (context_switch_summary_data[i].thread_id != 0) {
				print_context_data(context_switch_summary_data[i].thread_id,
					context_switch_summary_data[i].count,
					context_switch_summary_data[i].last_time_executed, i);
			}
		}

		/* Print sleep event data */
		PRINTF("\x1b[8;32HSLEEP EVENT DATA");
		PRINTF("\x1b[9;32H----------------");
		PRINTF("\x1b[10;32HLast sleep event received");
		if (sleep_event_data.last_time_slept > 0) {
			PRINTF("\x1b[11;32HExit cause : irq #%u   ",
				sleep_event_data.awake_cause);
			PRINTF("\x1b[12;32HAt tick    : %u        ",
				sleep_event_data.last_time_slept);
			PRINTF("\x1b[13;32HDuration   : %u ticks     ",
				sleep_event_data.last_duration);
		}

		/* Print interrupt event data */
		PRINTF("\x1b[15;32HINTERRUPT EVENT DATA");
		PRINTF("\x1b[16;32H--------------------");
		PRINTF("\x1b[17;32HInterrupt counters");

		int line = 0;

		for (i = 0; i < 255; i++) {
			if (interrupt_counters[i] > 0) {
				PRINTF("\x1b[%d;%dHirq #%d : %d times", 18 + line, 32, i,
					interrupt_counters[i]);
				line++;
			}
		}

#ifdef CONFIG_MICROKERNEL
		/* Print task monitor status data */
		PRINTF("\x1b[1;64HTASK MONITOR STATUS DATA");
		PRINTF("\x1b[2;64H-------------------------");
		PRINTF("\x1b[3;64HEvento\tTimestamp\tTaskId\tData");
		for (i = 0; i < MAX_BUFFER_CONTEXT_DATA; i++) {
			if (tmon_summary_data[i].timestamp != 0) {
				print_tmon_status_data(i);
			}
		}
#endif

		/* Sleep */
		fiber_sleep(50);
	}
}