| 413 | |
| 414 | #if HAL_MONITOR_THREAD_ENABLED |
| 415 | void Scheduler::_monitor_thread(void *arg) |
| 416 | { |
| 417 | Scheduler *sched = (Scheduler *)arg; |
| 418 | chRegSetThreadName("monitor"); |
| 419 | |
| 420 | while (!sched->_initialized) { |
| 421 | sched->delay(100); |
| 422 | } |
| 423 | bool using_watchdog = AP_BoardConfig::watchdog_enabled(); |
| 424 | #if HAL_LOGGING_ENABLED |
| 425 | uint8_t log_wd_counter = 0; |
| 426 | #endif |
| 427 | |
| 428 | while (true) { |
| 429 | sched->delay(100); |
| 430 | if (using_watchdog) { |
| 431 | stm32_watchdog_save((uint32_t *)&hal.util->persistent_data, (sizeof(hal.util->persistent_data)+3)/4); |
| 432 | } |
| 433 | |
| 434 | // if running memory guard then check all allocations |
| 435 | malloc_check(nullptr); |
| 436 | |
| 437 | uint32_t now = AP_HAL::millis(); |
| 438 | uint32_t loop_delay = now - sched->last_watchdog_pat_ms; |
| 439 | if (loop_delay >= 200) { |
| 440 | // the main loop has been stuck for at least |
| 441 | // 200ms. Starting logging the main loop state |
| 442 | #if HAL_LOGGING_ENABLED |
| 443 | const AP_HAL::Util::PersistentData &pd = hal.util->persistent_data; |
| 444 | if (AP_Logger::get_singleton()) { |
| 445 | const struct log_MON mon{ |
| 446 | LOG_PACKET_HEADER_INIT(LOG_MON_MSG), |
| 447 | time_us : AP_HAL::micros64(), |
| 448 | loop_delay : loop_delay, |
| 449 | current_task : pd.scheduler_task, |
| 450 | internal_error_mask : pd.internal_errors, |
| 451 | internal_error_count : pd.internal_error_count, |
| 452 | internal_error_line : pd.internal_error_last_line, |
| 453 | mavmsg : pd.last_mavlink_msgid, |
| 454 | mavcmd : pd.last_mavlink_cmd, |
| 455 | semline : pd.semaphore_line, |
| 456 | spicnt : pd.spi_count, |
| 457 | i2ccnt : pd.i2c_count |
| 458 | }; |
| 459 | AP::logger().WriteCriticalBlock(&mon, sizeof(mon)); |
| 460 | } |
| 461 | #endif |
| 462 | } |
| 463 | if (loop_delay >= 500 && !sched->in_expected_delay()) { |
| 464 | // at 500ms we declare an internal error |
| 465 | AP::internalerror().error(AP_InternalError::error_t::main_loop_stuck, hal.util->persistent_data.semaphore_line); |
| 466 | /* |
| 467 | if we are armed and get this condition then it is likely |
| 468 | a lock ordering deadlock. If the main thread is waiting |
| 469 | on a mutex then we try to force release the mutex from |
| 470 | the thread that is holding it. |
| 471 | */ |
| 472 | try_force_mutex(); |
nothing calls this directly
no test coverage detected