void os_idle_demon(void) { RTC_Init_TypeDef init; unsigned int sleep; /* The idle demon is a system thread, running when no other thread is */ /* ready to run. */ /* Enable system clock for RTC */ /* LFXO setup */ /* Use 70% boost */ CMU->CTRL = (CMU->CTRL & ~_CMU_CTRL_LFXOBOOST_MASK) | CMU_CTRL_LFXOBOOST_70PCENT; /* Ensure LE modules are accessible */ CMU_ClockEnable(cmuClock_CORELE, true); /* Enable osc as LFACLK in CMU (will also enable oscillator if not enabled) */ CMU_ClockSelectSet(cmuClock_LFA, cmuSelect_LFXO); /* Use a 32 division prescaler to reduce power consumption. */ CMU_ClockDivSet(cmuClock_RTC, cmuClkDiv_32); /* Enable clock to RTC module */ CMU_ClockEnable(cmuClock_RTC, true); init.enable = false; init.debugRun = false; init.comp0Top = false; /* Count to max value before wrapping */ RTC_Init(&init); /* Disable interrupt generation from RTC0 */ RTC_IntDisable(_RTC_IF_MASK); /* Enable interrupts */ NVIC_ClearPendingIRQ(RTC_IRQn); NVIC_EnableIRQ(RTC_IRQn); for (;;) { /* os_suspend stops scheduler and returns time to next event in OS_TICK units */ sleep = os_suspend(); if (sleep) { RTC_CompareSet(0, sleep - 1); RTC_IntClear(RTC_IFC_COMP0); RTC_IntEnable(RTC_IF_COMP0); RTC_CounterReset(); /* Enter EM2 low power mode - could be replaced with EM1 if required */ EMU_EnterEM2(true); /* get information how long we were in sleep */ sleep = RTC_CounterGet(); RTC_Enable(false); }; /* resume scheduler providing information how long MCU was sleeping */ os_resume(sleep); } }
int main(void) { //printf("\r\n***** threaded blinky uvisor-rtos example *****\r\n"); putc('*', stdout); fflush(stdout); size_t count = 0; /* Startup a few RPC runners. */ static const uint32_t stack_size = 512; Thread * sync_1 = new(std::nothrow) Thread(sync_runner, &main_sync_1, osPriorityNormal, stack_size); Thread * sync_2 = new(std::nothrow) Thread(sync_runner, &main_sync_2, osPriorityNormal, stack_size); Thread * sync_3 = new(std::nothrow) Thread(sync_runner, &main_sync_3, osPriorityNormal, stack_size); Thread * async_1 = new(std::nothrow) Thread(async_runner, &main_async_1, osPriorityNormal, stack_size); Thread * async_2 = new(std::nothrow) Thread(async_runner, &main_async_2, osPriorityNormal, stack_size); Thread * async_3 = new(std::nothrow) Thread(async_runner, &main_async_3, osPriorityNormal, stack_size); if (sync_1 == NULL || sync_2 == NULL || sync_3 == NULL || async_1 == NULL || async_2 == NULL || async_3 == NULL) { uvisor_error(USER_NOT_ALLOWED); } while (1) { #define STATS_ENABLED 0 #if STATS_ENABLED uint32_t ticks_can_suspend = os_suspend(); puts("\r\n>---------------------------------------\r\n"); printf("ticks_can_suspend: %lu\r\n", ticks_can_suspend); printf("green_handler_a_1: %u\r\n", green_handler_a_1.num_handled); printf("green_handler_a_2: %u\r\n", green_handler_a_2.num_handled); printf("green_handler_ab_1: %u\r\n", green_handler_ab_1.num_handled); printf("green_handler_c_1: %u\r\n", green_handler_c_1.num_handled); puts("<---------------------------------------\r\n"); os_resume(0); /* Pretend no ticks went by while suspended. */ #endif /* Spin forever. */ Thread::wait(10000); } return 0; }
void os_idle_demon (void) { unsigned int expected_time; unsigned int prev_time; for (;; ) { rtos_suspend = 1; expected_time = os_suspend(); expected_time &= TIMER_MASK; if (expected_time > 2) { prev_time = NRF_RTC1->COUNTER; expected_time += prev_time; NRF_RTC1->CC[0] = (expected_time > TIMER_MASK) ? expected_time - TIMER_MASK : expected_time; NRF_RTC1->INTENCLR = RTC_INTENSET_TICK_Msk; NVIC_EnableIRQ(RTC1_IRQn); __disable_irq(); if (rtos_suspend) { NRF_RTC1->INTENSET = RTC_INTENSET_COMPARE0_Msk; __WFI(); NRF_RTC1->EVENTS_COMPARE[0] = 0; NRF_RTC1->INTENCLR = RTC_INTENSET_COMPARE0_Msk; } __enable_irq(); NRF_RTC1->INTENSET = RTC_INTENSET_TICK_Msk; expected_time = NRF_RTC1->COUNTER; expected_time = (expected_time >= prev_time) ? expected_time - prev_time : TIMER_MASK - prev_time + expected_time; } os_resume(expected_time); } }