5 #pragma GCC optimize ("O2") 52 #define STACK_GUARD 0x60a4d51aL 97 revo_sched_log Scheduler::logbuf[SHED_DEBUG_SIZE]
IN_CCM;
98 uint16_t Scheduler::sched_log_ptr;
107 uint32_t Scheduler::MPU_overflow_cnt
IN_CCM;
108 uint32_t Scheduler::MPU_restart_cnt
IN_CCM;
109 uint32_t Scheduler::MPU_count
IN_CCM;
110 uint32_t Scheduler::MPU_Time
IN_CCM;
149 NVIC_ClearPendingIRQ(TIM6_DAC_IRQn);
158 AP_HAL::panic(
"HAL initialization on ISR level=0x%x", (uint8_t)(SCB->ICSR & SCB_ICSR_VECTACTIVE_Msk));
176 asm volatile(
"dsb \n");
177 asm volatile(
"isb \n");
182 CLEAR_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk));
183 SET_BIT( SCB->SCR, ((uint32_t)SCB_SCR_SEVONPEND_Msk));
193 uint32_t period = (2000000UL /
SHED_FREQ) - 1;
265 uint32_t dt = ms * 1000;
268 while((now=
_micros()) - start < dt) {
303 #define NO_YIELD_TIME 8 // uS 347 static bool init_done=
false;
443 static uint32_t last_failsafe=0;
445 if(t-last_failsafe>10){
446 last_failsafe = t+50;
457 asm volatile (
"MRS %0, PSP\n\t" :
"=rm" (sp));
461 static uint32_t last_timer_procs=0;
465 if(now - last_timer_procs >= 1000) {
466 last_timer_procs = now;
493 #pragma pack(push, 1) 510 #ifndef I_KNOW_WHAT_I_DO 512 AP_HAL::panic(
"PANIC: scheduler::system_initialized called more than once");
523 if(hold_in_bootloader) {
578 static float shed_eff=0;
580 if(
is_zero(shed_eff)) shed_eff = eff;
581 else shed_eff = shed_eff*(1 - 1/Kf) + eff*(1/Kf);
583 printf(
"\nSched stats: uptime %lds\n %% of full time: %5.2f Efficiency %5.3f max loop time %ld\n", t/1000, (
task_time/10.0)/t , shed_eff,
max_loop_time);
588 printf(
"\nISR time %5.2f max %5.2f", (isr_time/10.0/(
float)
us_ticks)/t, max_isr_time/(
float)us_ticks );
592 printf(
"MPU overflows: %ld restarts %ld max samples %ld time %ld\n", MPU_overflow_cnt, MPU_restart_cnt, MPU_count, MPU_Time); MPU_overflow_cnt=0; MPU_restart_cnt=0; MPU_count=0; MPU_Time=0;
614 printf(
"task %d (0x%015llx) time: %7.2f%% mean %8.1fuS max %5lduS full %7lduS wait sem. %6lduS free stack 0x%lx\n",
636 for(uint8_t i=0; i<n; i++){
645 uint32_t heap_ptr = (uint32_t)
__brkval;
646 uint32_t bottom = (uint32_t)&
_sdata;
649 printf(
"\nMemory used: static %ldk full %ldk\n",((uint32_t)&
_edata-bottom+1023)/1024, (heap_ptr-bottom+1023)/1024);
670 printf(
"IO completion effectiveness=%7.3f%%\n", 100.0 * iot/
ioc_time);
709 #pragma GCC diagnostic push 710 #pragma GCC diagnostic ignored "-Wcast-align" // yes I know 713 #pragma GCC diagnostic pop 720 #pragma GCC diagnostic push 721 #pragma GCC diagnostic ignored "-Wcast-align" 723 #pragma GCC diagnostic pop 736 #if 0 // once started tasks are never ended 742 if(ptr->handler ==
NULL)
return ptr;
818 memset(&tp,0,
sizeof(tp));
829 return (uint32_t)&tp;
834 #pragma GCC diagnostic push 835 #pragma GCC diagnostic ignored "-Wcast-align" // yes I know 839 #pragma GCC diagnostic pop 849 uint32_t *sp =(uint32_t *) (((uint32_t)task - 4) & 0xFFFFFFF8UL);
852 *(--sp) = 0x01000000UL;
855 *(--sp) = ((uint32_t)
do_task)|1;
857 *(--sp) = (uint32_t)task;
859 *(--sp) = 0xFFFFFFFDUL;
863 "STMDB R0!, {R4-R11}\n\t" :
"+rm" (sp) );
868 task->
sp=(uint8_t *)sp;
885 AP_HAL::panic(
"start_task called from ISR 0x%x", (uint8_t)(SCB->ICSR & SCB_ICSR_VECTACTIVE_Msk));
893 stackSize +=
sizeof(
task_t)+8;
924 static uint16_t next_log_ptr(uint16_t sched_log_ptr){
925 uint16_t lp = sched_log_ptr+ 1;
926 if(lp >= SHED_DEBUG_SIZE) lp=0;
936 if(tmp==0 || me->
id == 0) {
943 printf(
"\nTaks %d killed by exception %d!\n",me->
id, n);
966 uint32_t timeFromLast=0;
967 uint32_t remains = 0;
969 uint32_t partial_quant=(uint32_t)-1;
980 #if defined(MTASK_PROF) 981 uint32_t dt = now - me->
start;
997 revo_sched_log &lp = logbuf[sched_log_ptr];
1003 sched_log_ptr = next_log_ptr(sched_log_ptr);
1004 ZeroIt(logbuf[sched_log_ptr]);
1016 bool was_yield=
false;
1021 #if !defined(USE_MPU) || 1 1023 printf(
"PANIC: stack guard spoiled in process %d (from %d)\n", task->
id, me->
id);
1029 if(!ptr->
handle)
goto skip_task;
1062 if( timeFromLast < ptr->period) {
1063 remains = ptr->
period - timeFromLast;
1065 if(remains<partial_quant && ptr->curr_prio <= want_tail->curr_prio) {
1066 partial_quant=remains;
1080 timeFromLast = now - ptr->
t_yield;
1081 if(timeFromLast < ptr->ttw){
1082 remains = ptr->
ttw - timeFromLast;
1084 if(remains<partial_quant && ptr->curr_prio <= want_tail->curr_prio) {
1085 partial_quant=remains;
1126 revo_sched_log &lp = logbuf[sched_log_ptr];
1128 lp.task_id=task->
id;
1130 lp.active = task->
active;
1132 lp.quant = partial_quant;
1133 lp.want_tail = want_tail;
1134 ZeroIt(logbuf[next_log_ptr(sched_log_ptr)]);
1139 #if defined(MTASK_PROF) 1201 asm volatile(
"svc 0");
1210 unsigned char marker;
1274 #pragma GCC optimize ("O2") // should ALWAYS be -O2 for tail recursion optimization in PendSV_Handler 1282 #if defined(USE_MPU) 1294 uint32_t * svc_args;
1302 :
"=rm" (svc_args) );
1311 unsigned int svc_number = ((
char *)svc_args[6])[-2];
1314 switch(svc_number) {
1339 uint32_t timeout_ms = svc_args[1];
1340 svc_args[0] = ret = sem->
svc_take(timeout_ms);
1349 curr_task->
sem_time = timeout_ms*1000;
bool svc_take_nonblocking()
void revo_call_handler(uint64_t hh, uint32_t arg)
void(* voidFuncPtr)(void)
#define ADDRESS_IN_CCM(a)
static uint32_t stopwatch_getticks()
#define MPU_CTRL_PRIVDEFENA
int printf(const char *fmt,...)
bool get_soft_armed() const
uint8_t get_last_error_state()
static void _timer5_ovf(uint32_t v)
static void context_switch_isr()
static INLINE void noInterrupts()
static void mpu_disable()
static uint32_t tsched_count_y
void hal_stop_multitask()
static void switch_task()
#define FORCE_APP_RTC_SIGNATURE
static uint32_t tsched_sw_count_t
AP_HAL::UARTDriver * console
static size_t task_stack()
void timer_reset(const timer_dev *dev)
static INLINE void interrupts()
static uint32_t tsched_sw_count
static AP_HAL::Proc _failsafe
static void set_task_semaphore(void *h, F4Light::Semaphore *sem)
void hal_set_task_priority(void *h, uint8_t prio)
static void set_task_priority(void *h, uint8_t prio)
static uint32_t tick_micros
void * hal_register_task(voidFuncPtr task, uint32_t stack)
static uint64_t delay_time
static uint8_t num_io_completion
static void * get_current_task()
virtual void register_delay_callback(AP_HAL::Proc, uint16_t min_time_ms)
static void _run_timer_procs(bool called_from_isr)
static void enqueue_task(task_t &tp)
#define HAL_SEMAPHORE_BLOCK_FOREVER
static bool in_interrupt()
bool svc_take(uint32_t timeout_ms)
static void _try_kill_task_or_reboot(uint8_t n)
static uint32_t tsched_count
static uint64_t delay_int_time
static void _set_10s_flag()
static INLINE void timer_pause(const timer_dev *dev)
Stop a timer's counter from changing.
static void _print_stats()
static INLINE void timer_set_count(const timer_dev *dev, uint16_t value)
Sets the counter value for the given timer.
static void _register_io_process(Handler h, Revo_IO_Flags flags)
-*- tab-width: 4; Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*-
static void set_task_active(void *h)
void timer_attach_interrupt(const timer_dev *dev, timer_interrupt_id interrupt, Handler handler, uint8_t priority)
Attach a timer interrupt.
static void _switch_task()
static void _timer_isr_event(uint32_t v)
static uint32_t max_wfe_time
static void _reboot(bool hold_in_bootloader)
void register_delay_callback(AP_HAL::Proc, uint16_t min_time_ms) override
static INLINE void timer_resume(const timer_dev *dev)
Start a timer's counter.
static uint32_t timer5_ovf_cnt
static void plan_context_switch()
static void check_stack(uint32_t sp)
void hal_try_kill_task_or_reboot(uint8_t n)
static uint32_t max_delay_err
#define MPU_RASR_ATTR_AP_RO_RO
void system_initialized()
static void * init_task(uint64_t h, const uint8_t *stack)
static Handler on_disarm_handler
static uint8_t _num_io_proc
static uint32_t _millis()
#define BOOT_RTC_SIGNATURE
static uint64_t _micros64()
static uint8_t get_dev_count()
bool is_zero(const T fVal1)
void hal_set_task_active(void *h)
static void * _start_task(Handler h, size_t stackSize)
static void _delay_us_ny(uint16_t us)
static void SVC_Handler(uint32_t *svc_args)
static void set_task_period(void *h, uint32_t period)
void println(const char *str)
static uint32_t lowest_stack
void hal_isr_time(uint32_t t)
F4Light::Semaphore * sem_wait
virtual void call_delay_cb()
static uint32_t tsched_count_t
static void yield(uint16_t ttw=0)
static bool _in_main_thread()
uint16_t _min_delay_cb_ms
void hal_context_switch_isr()
static uint64_t shed_time
static bool adjust_timer_task(AP_HAL::Device::PeriodicHandle h, uint32_t period_us)
static void _run_io(void)
static void timer_enable_irq(const timer_dev *dev, timer_interrupt_id interrupt)
Enable a timer interrupt.
static void _delay_microseconds_boost(uint16_t us)
static struct IO_COMPLETION io_completion[MAX_IO_COMPLETION]
static void mpu_enable(uint32_t ctrl)
static uint32_t _micros()
static Revo_IO _io_proc[F4Light_SCHEDULER_MAX_IO_PROCS]
static uint64_t task_time
void hal_yield(uint16_t ttw)
static bool unregister_timer_task(AP_HAL::Device::PeriodicHandle h)
static F4Light::I2CDevice * get_device(uint8_t i)
bool take(uint32_t timeout_ms)
void hal_delay(uint16_t t)
static uint32_t tsched_sw_count_y
static uint64_t sleep_time
static uint64_t tick_fulltime
static void _delay(uint16_t ms)
static void do_task(task_t *task)
uint32_t get_error_count()
static uint32_t tick_count
static task_t * _forced_task
AP_HAL::Proc Scheduler::_failsafe IN_CCM
void board_set_rtc_register(uint32_t sig, uint16_t reg)
uint32_t configTimeBase(const timer_dev *dev, uint16_t period, uint16_t khz)
static task_t * get_empty_task()
static void dequeue_task(task_t &tp)
static uint32_t max_loop_time
#define DFU_RTC_SIGNATURE
static void mpu_configure_region(uint8_t region, uint32_t addr, uint32_t attribs)
static AP_HAL::Device::PeriodicHandle _register_timer_task(uint32_t period_us, Handler proc, F4Light::Semaphore *sem)
static void _stop_multitask()
static INLINE void timer_set_reload(const timer_dev *dev, uint32_t arr)
Set a timer's reload value.
void panic(const char *errormsg,...) FMT_PRINTF(1
#define RTC_SIGNATURE_REG
static void _delay_microseconds(uint16_t us)
#define MPU_RASR_ATTR_NON_CACHEABLE
#define SYSTICK_INT_PRIORITY
#define PENDSV_INT_PRIORITY
static void _go_next_task()
static void * _delay_cb_handle
void timer_foreach(void(*fn)(const timer_dev *))
Call a function on timer devices.
static task_t * get_next_task()
static bool is_bare_metal()
static task_t * _idle_task
static uint32_t fill_task(task_t &tp)
static void stop_task(void *h)
void hal_delay_microseconds(uint16_t t)
#define MAX_IO_COMPLETION
void __do_context_switch()
static void * start_task(voidFuncPtr taskLoop, size_t stackSize=DEFAULT_STACK_SIZE)
#define F4Light_SCHEDULER_MAX_IO_PROCS
AP_HAL::Scheduler * scheduler
static void _ioc_timer_event(uint32_t v)
void reboot(bool hold_in_bootloader)
static void _tail_timer_event(uint32_t v)
static volatile bool need_switch_task
static void timer_generate_update(const timer_dev *dev)
Generate an update event for the given timer.
static uint8_t register_io_completion(Handler handle)
static void start_stats_task()
#define ADDRESS_IN_FLASH(a)