/* * This file is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This file is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . * * Code by Andrew Tridgell and Siddharth Bharat Purohit */ #pragma once #include #if CONFIG_HAL_BOARD == HAL_BOARD_CHIBIOS #include "AP_HAL_ChibiOS_Namespace.h" #define CHIBIOS_SCHEDULER_MAX_TIMER_PROCS 8 #define APM_MONITOR_PRIORITY 183 #define APM_MAIN_PRIORITY 180 #define APM_TIMER_PRIORITY 181 #define APM_RCOUT_PRIORITY 181 #define APM_RCIN_PRIORITY 177 #define APM_LED_PRIORITY 60 #define APM_UART_PRIORITY 60 #define APM_UART_UNBUFFERED_PRIORITY 181 #define APM_STORAGE_PRIORITY 59 #define APM_IO_PRIORITY 58 #define APM_STARTUP_PRIORITY 10 #define APM_SCRIPTING_PRIORITY LOWPRIO /* boost priority handling */ #ifndef APM_MAIN_PRIORITY_BOOST #define APM_MAIN_PRIORITY_BOOST 182 #endif #ifndef APM_SPI_PRIORITY // SPI priority needs to be above main priority to ensure fast sampling of IMUs can keep up // with the data rate #define APM_SPI_PRIORITY 181 #endif #ifndef APM_CAN_PRIORITY #define APM_CAN_PRIORITY 178 #endif #ifndef APM_I2C_PRIORITY #define APM_I2C_PRIORITY 176 #endif #ifndef TIMER_THD_WA_SIZE #define TIMER_THD_WA_SIZE 1536 #endif #ifndef RCOUT_THD_WA_SIZE #define RCOUT_THD_WA_SIZE 512 #endif #ifndef RCIN_THD_WA_SIZE #define RCIN_THD_WA_SIZE 1024 #endif #ifndef IO_THD_WA_SIZE #define IO_THD_WA_SIZE 2048 #endif #ifndef STORAGE_THD_WA_SIZE #define STORAGE_THD_WA_SIZE 1024 #endif #ifndef MONITOR_THD_WA_SIZE #define MONITOR_THD_WA_SIZE 1024 #endif /* Scheduler implementation: */ class ChibiOS::Scheduler : public AP_HAL::Scheduler { public: Scheduler(); /* AP_HAL::Scheduler methods */ void init() override; void delay(uint16_t ms) override; void delay_microseconds(uint16_t us) override; void delay_microseconds_boost(uint16_t us) override; void boost_end(void) override; void register_timer_process(AP_HAL::MemberProc) override; void register_io_process(AP_HAL::MemberProc) override; void register_timer_failsafe(AP_HAL::Proc, uint32_t period_us) override; void reboot(bool hold_in_bootloader) override; bool in_main_thread() const override { return get_main_thread() == chThdGetSelfX(); } void set_system_initialized() override; bool is_system_initialized() override { return _initialized; }; void hal_initialized() { _hal_initialized = true; } bool check_called_boost(void); /* inform the scheduler that we are calling an operation from the main thread that may take an extended amount of time. This can be used to prevent watchdog reset during expected long delays A value of zero cancels the previous expected delay */ void _expect_delay_ms(uint32_t ms); void expect_delay_ms(uint32_t ms) override; /* return true if we are in a period of expected delay. This can be used to suppress error messages */ bool in_expected_delay(void) const override; /* disable interrupts and return a context that can be used to restore the interrupt state. This can be used to protect critical regions */ void *disable_interrupts_save(void) override; /* restore interrupt state from disable_interrupts_save() */ void restore_interrupts(void *) override; /* create a new thread */ bool thread_create(AP_HAL::MemberProc, const char *name, uint32_t stack_size, priority_base base, int8_t priority) override; // pat the watchdog void watchdog_pat(void); private: bool _initialized; volatile bool _hal_initialized; AP_HAL::Proc _failsafe; bool _called_boost; bool _priority_boosted; uint32_t expect_delay_start; uint32_t expect_delay_length; uint32_t expect_delay_nesting; HAL_Semaphore expect_delay_sem; AP_HAL::MemberProc _timer_proc[CHIBIOS_SCHEDULER_MAX_TIMER_PROCS]; uint8_t _num_timer_procs; volatile bool _in_timer_proc; AP_HAL::MemberProc _io_proc[CHIBIOS_SCHEDULER_MAX_TIMER_PROCS]; uint8_t _num_io_procs; volatile bool _in_io_proc; uint32_t last_watchdog_pat_ms; thread_t* _timer_thread_ctx; thread_t* _rcout_thread_ctx; thread_t* _rcin_thread_ctx; thread_t* _io_thread_ctx; thread_t* _storage_thread_ctx; thread_t* _monitor_thread_ctx; #if CH_CFG_USE_SEMAPHORES == TRUE binary_semaphore_t _timer_semaphore; binary_semaphore_t _io_semaphore; #endif // calculates an integer to be used as the priority for a newly-created thread uint8_t calculate_thread_priority(priority_base base, int8_t priority) const; static void _timer_thread(void *arg); static void _rcout_thread(void *arg); static void _rcin_thread(void *arg); static void _io_thread(void *arg); static void _storage_thread(void *arg); static void _uart_thread(void *arg); static void _monitor_thread(void *arg); void _run_timers(); void _run_io(void); static void thread_create_trampoline(void *ctx); #if defined STM32H7 void check_low_memory_is_zero(); #endif // check for free stack space void check_stack_free(void); }; #endif