void shutdown_worker(void *arg) { PX4_DEBUG("shutdown worker (%i)", shutdown_counter); bool done = true; pthread_mutex_lock(&shutdown_mutex); for (int i = 0; i < max_shutdown_hooks; ++i) { if (shutdown_hooks[i]) { if (!shutdown_hooks[i]()) { done = false; } } } if ((done && shutdown_lock_counter == 0) || ++shutdown_counter > shutdown_timeout_ms / 10) { if (shutdown_args & SHUTDOWN_ARG_REBOOT) { PX4_WARN("Reboot NOW."); px4_systemreset(shutdown_args & SHUTDOWN_ARG_TO_BOOTLOADER); } else { PX4_WARN("Shutdown NOW. Good Bye."); board_shutdown(); } pthread_mutex_unlock(&shutdown_mutex); // must NEVER come here } else { pthread_mutex_unlock(&shutdown_mutex); work_queue(HPWORK, &shutdown_work, (worker_t)&shutdown_worker, nullptr, USEC2TICK(10000)); } }
/* Everything needed to cleanly shutdown barebox. * Should be called before starting an OS to get * the devices into a clean state */ void shutdown_barebox(void) { devices_shutdown(); #ifdef ARCH_SHUTDOWN arch_shutdown(); #endif if (board_shutdown) board_shutdown(); }
int px4_shutdown_request(bool reboot, bool to_bootloader) { int ret = 0; pthread_mutex_lock(&shutdown_mutex); // FIXME: if shutdown_lock_counter > 0, we should wait, but unfortunately we don't have work queues if (reboot) { px4_systemreset(to_bootloader); } else { ret = board_shutdown(); } pthread_mutex_unlock(&shutdown_mutex); return ret; }
static int board_button_irq(int irq, FAR void *context) { static struct timespec time_down; if (board_pwr_button_down()) { led_on(BOARD_LED_RED); clock_gettime(CLOCK_REALTIME, &time_down); power_state_notification(PWR_BUTTON_DOWN); } else { power_state_notification(PWR_BUTTON_UP); led_off(BOARD_LED_RED); struct timespec now; clock_gettime(CLOCK_REALTIME, &now); uint64_t tdown_ms = time_down.tv_sec * 1000 + time_down.tv_nsec / 1000000; uint64_t tnow_ms = now.tv_sec * 1000 + now.tv_nsec / 1000000; if (tdown_ms != 0 && (tnow_ms - tdown_ms) >= MS_PWR_BUTTON_DOWN) { led_on(BOARD_LED_BLUE); if (power_state_notification(PWR_BUTTON_REQUEST_SHUT_DOWN) == PWR_BUTTON_RESPONSE_SHUT_DOWN_NOW) { up_mdelay(200); board_shutdown(); } } else { power_state_notification(PWR_BUTTON_IDEL); } } return OK; }