/** * Initialize the resources used by the framework's timer services * * IMPORTANT : this function must be called during the initialization * of the OS abstraction layer. * this function shall only be called once after reset, otherwise * it may cause the take/lock and give/unlock services to fail */ void framework_init_timer(void) { uint8_t idx; #ifdef CONFIG_NANOKERNEL nano_sem_init ( &g_TimerSem ); nano_timer_init (&g_NanoTimer, &g_NanoTimerData); #else g_TimerSem = OS_TIMER_SEM; #endif /* start with empty list of active timers: */ g_CurrentTimerHead = NULL; /* memset ( g_TimerPool_elements, 0 ): */ for (idx = 0; idx < TIMER_POOL_SIZE; idx++) { g_TimerPool_elements[idx].desc.callback = NULL; g_TimerPool_elements[idx].desc.data = NULL; g_TimerPool_elements[idx].desc.delay = 0; g_TimerPool_elements[idx].desc.expiration = 0; g_TimerPool_elements[idx].desc.repeat = false; g_TimerPool_elements[idx].prev = NULL; g_TimerPool_elements[idx].next = NULL; /* hopefully, the init function is performed before * timer_create and timer_stop can be called, * hence there is no need for a critical section * here */ } /* start "timer_task" in a new fiber for NanoK, or a new task for microK */ #ifdef CONFIG_NANOKERNEL fiber_fiber_start ((char *) g_TimerFiberStack, TIMER_CBK_TASK_STACK_SIZE, timer_task,0,0, TIMER_CBK_TASK_PRIORITY, TIMER_CBK_TASK_OPTIONS); #else task_start(OS_TASK_TIMER); #endif }
int fiber_yieldTest(void) { nano_thread_id_t self_thread_id; /* * Start a fiber of higher priority. Note that since the new fiber is * being started from a fiber, it will not automatically switch to the * fiber as it would if done from a task. */ self_thread_id = sys_thread_self_get(); fiberEvidence = 0; fiber_fiber_start(fiberStack2, FIBER_STACKSIZE, fiberHelper, 0, 0, FIBER_PRIORITY - 1, 0); if (fiberEvidence != 0) { /* ERROR! Helper spawned at higher */ fiberDetectedError = 10; /* priority ran prematurely. */ return TC_FAIL; } /* * Test that the fiber will yield to the higher priority helper. * <fiberEvidence> is still 0. */ fiber_yield(); if (fiberEvidence == 0) { /* ERROR! Did not yield to higher */ fiberDetectedError = 11; /* priority fiber. */ return TC_FAIL; } if (fiberEvidence > 1) { /* ERROR! Helper did not yield to */ fiberDetectedError = 12; /* equal priority fiber. */ return TC_FAIL; } /* * Raise the priority of fiberEntry(). Calling fiber_yield() should * not result in switching to the helper. */ self_thread_id->prio--; fiber_yield(); if (fiberEvidence != 1) { /* ERROR! Context switched to a lower */ fiberDetectedError = 13; /* priority fiber! */ return TC_FAIL; } /* * Block on <wakeFiber>. This will allow the helper fiber to complete. * The main task will wake this fiber. */ nano_fiber_sem_take(&wakeFiber, TICKS_UNLIMITED); return TC_PASS; }