Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
e9cbbdb
fix (tested on PCU, LV-BMS and LCU)
victor-Lopez25 Mar 20, 2026
773c446
get cleanup to compile
victor-Lopez25 Mar 20, 2026
5418b89
format checks
victor-Lopez25 Mar 20, 2026
7231bfd
fix tests and scheduler (off by one error)
victor-Lopez25 Mar 20, 2026
f60c159
Add a test for get_at
victor-Lopez25 Mar 20, 2026
643d2c8
formatting
victor-Lopez25 Mar 20, 2026
8629f5e
Add a test for set_at and fix it
victor-Lopez25 Mar 20, 2026
175dc80
formatting
victor-Lopez25 Mar 20, 2026
9862b38
formatting
victor-Lopez25 Mar 20, 2026
cb381bf
try to fix issue in LCU
victor-Lopez25 Mar 20, 2026
1c489af
add a test for front_id and pop_front
victor-Lopez25 Mar 20, 2026
f1171b4
Merge remote-tracking branch 'origin/development' into fix/scheduler-…
victor-Lopez25 Mar 20, 2026
3c16640
add changeset for this pr
victor-Lopez25 Mar 20, 2026
e49afea
formatting for changeset :/
victor-Lopez25 Mar 20, 2026
fb9fa43
fix (tested on PCU, LV-BMS and LCU)
victor-Lopez25 Mar 20, 2026
3eb88ab
get cleanup to compile
victor-Lopez25 Mar 20, 2026
6f2eaf8
format checks
victor-Lopez25 Mar 20, 2026
d07b4bb
fix tests and scheduler (off by one error)
victor-Lopez25 Mar 20, 2026
c199f42
Add a test for get_at
victor-Lopez25 Mar 20, 2026
d40395e
formatting
victor-Lopez25 Mar 20, 2026
df98f27
Add a test for set_at and fix it
victor-Lopez25 Mar 20, 2026
b0a91cd
formatting
victor-Lopez25 Mar 20, 2026
6dd5494
formatting
victor-Lopez25 Mar 20, 2026
1d96793
try to fix issue in LCU
victor-Lopez25 Mar 20, 2026
6e500e4
add a test for front_id and pop_front
victor-Lopez25 Mar 20, 2026
7a58320
revert merge from development
victor-Lopez25 Mar 23, 2026
8cad77f
searching for case-insensitive STM32 CLT path
jorgesg82 Mar 26, 2026
379319e
applied formatter
jorgesg82 Mar 26, 2026
8212c6c
removed unused include
jorgesg82 Mar 26, 2026
d14ece9
making PacketValue destructor virtual so that CLang doesn't cry
jorgesg82 Mar 26, 2026
581bb19
minor fix
jorgesg82 Mar 26, 2026
29467e2
commit old changes
victor-Lopez25 Mar 28, 2026
b24b1fe
Merge branch 'fix/scheduler-race-cond-part2' of https://github.com/Hy…
victor-Lopez25 Mar 28, 2026
b6ead59
fix off by one error in allocating a slot
victor-Lopez25 Mar 28, 2026
97473f0
formatting
victor-Lopez25 Mar 28, 2026
6c26813
fix old compile error which shouldn't be one
victor-Lopez25 Apr 1, 2026
84f0293
Add set_limit_value to set arr in TimerWrapper
victor-Lopez25 Apr 1, 2026
1924930
Merge remote-tracking branch 'origin/development' into fix/scheduler-…
victor-Lopez25 Apr 2, 2026
a3e7392
fix indentation
victor-Lopez25 Apr 2, 2026
e1a4185
indentation, again
victor-Lopez25 Apr 2, 2026
0aaac75
formatting
victor-Lopez25 Apr 2, 2026
ce5c4a6
Move errorhandler away from interrupt callback
victor-Lopez25 Apr 2, 2026
2602f10
ErrorHandler -> WARNING, prescaler calc -> TimerDomain
victor-Lopez25 Apr 2, 2026
2e3ae8d
formatting
victor-Lopez25 Apr 2, 2026
6e9b99e
Add Infowarning to tests, hopefully this compiles
victor-Lopez25 Apr 2, 2026
fa53ac6
formatting, and try to compile tests
victor-Lopez25 Apr 2, 2026
3d30a78
formatting
victor-Lopez25 Apr 2, 2026
3082bd2
formatting again
victor-Lopez25 Apr 2, 2026
6f15c38
change changeset to minor
victor-Lopez25 Apr 2, 2026
f7aa319
remove ErrorHandler in TIM_IC_CaptureCallback since it's an interrupt…
victor-Lopez25 Apr 2, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions Inc/HALAL/Services/Time/Scheduler.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,7 @@ struct Scheduler {
// temporary, will be removed
[[deprecated]] static inline void start() {}
static void update();
static inline uint64_t get_global_tick() {
return global_tick_us_ + Scheduler_global_timer->CNT;
}
static uint64_t get_global_tick();

static uint16_t register_task(uint32_t period_us, callback_t func);
static bool unregister_task(uint16_t id);
Expand Down
43 changes: 26 additions & 17 deletions Src/HALAL/Services/Time/Scheduler.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Scheduler.hpp
* Scheduler.cpp
*
* Created on: 17 nov. 2025
* Author: Victor (coauthor Stephan)
Expand Down Expand Up @@ -32,13 +32,11 @@ uint32_t Scheduler::current_interval_us_{0};
uint16_t Scheduler::timeout_idx_{1};

inline uint8_t Scheduler::get_at(uint8_t idx) {
int word_idx = idx > 7;
uint32_t shift = (idx & 7) << 2;
return (((uint32_t*)&sorted_task_ids_)[word_idx] & (0x0F << shift)) >> shift;
return (uint8_t)((sorted_task_ids_ >> (idx * 4)) & 0xF);
}
inline void Scheduler::set_at(uint8_t idx, uint8_t id) {
uint32_t shift = idx * 4;
uint64_t clearmask = ~(0xFF << shift);
uint64_t clearmask = ~(0xFFULL << shift);
Scheduler::sorted_task_ids_ = (sorted_task_ids_ & clearmask) | (id << shift);
}
inline uint8_t Scheduler::front_id() { return *((uint8_t*)&sorted_task_ids_) & 0xF; }
Expand Down Expand Up @@ -159,18 +157,25 @@ void Scheduler::update() {
while (ready_bitmap_ != 0u) {
uint32_t bit_index = static_cast<uint32_t>(__builtin_ctz(ready_bitmap_));

CLEAR_BIT(ready_bitmap_, 1u << bit_index);

Task& task = tasks_[bit_index];
task.callback();

SchedLock();
Comment thread
victor-Lopez25 marked this conversation as resolved.
CLEAR_BIT(ready_bitmap_, 1u << bit_index);
if (!task.repeating) [[unlikely]] {
SchedLock();
release_slot(static_cast<uint8_t>(bit_index));
SchedUnlock();
}
SchedUnlock();
}
}

uint64_t Scheduler::get_global_tick() {
SchedLock();
uint64_t val = global_tick_us_ + Scheduler_global_timer->CNT;
Comment thread
victor-Lopez25 marked this conversation as resolved.
SchedUnlock();
return val;
}

inline uint8_t Scheduler::allocate_slot() {
uint32_t idx = __builtin_ffs(Scheduler::free_bitmap_) - 1;
if (idx > static_cast<int>(Scheduler::kMaxTasks)) [[unlikely]]
Expand Down Expand Up @@ -272,9 +277,12 @@ void Scheduler::schedule_next_interval() {
return;
}

SchedLock();
Comment thread
victor-Lopez25 marked this conversation as resolved.
uint8_t next_id = Scheduler::front_id(); // sorted_task_ids_[0]
Task& next_task = tasks_[next_id];
int32_t diff = (int32_t)(next_task.next_fire_us - static_cast<uint32_t>(global_tick_us_));
SchedUnlock();

if (diff >= -1 && diff <= 1) [[unlikely]] {
current_interval_us_ = 1;
SET_BIT(Scheduler_global_timer->EGR, TIM_EGR_UG); // This should cause an interrupt
Expand All @@ -284,12 +292,12 @@ void Scheduler::schedule_next_interval() {
} else {
current_interval_us_ = static_cast<uint32_t>(diff);
}
Scheduler_global_timer->ARR = static_cast<uint32_t>(current_interval_us_ - 1u);
while (Scheduler_global_timer->CNT > Scheduler_global_timer->ARR) [[unlikely]] {
uint32_t offset = Scheduler_global_timer->CNT - Scheduler_global_timer->ARR;
current_interval_us_ = offset;
SET_BIT(Scheduler_global_timer->EGR, TIM_EGR_UG); // This should cause an interrupt
Scheduler_global_timer->CNT = Scheduler_global_timer->CNT + offset;

Scheduler_global_timer->ARR = current_interval_us_ - 1u;
Comment thread
victor-Lopez25 marked this conversation as resolved.
if (Scheduler_global_timer->CNT > current_interval_us_) [[unlikely]] {
uint32_t offset = Scheduler_global_timer->CNT - current_interval_us_;
Scheduler_global_timer->CNT = 0;
global_tick_us_ += offset;
Comment thread
victor-Lopez25 marked this conversation as resolved.
Outdated
}
}
Scheduler::global_timer_enable();
Comment thread
victor-Lopez25 marked this conversation as resolved.
Expand All @@ -305,15 +313,16 @@ void Scheduler::on_timer_update() {
if (diff > 0) [[likely]] {
break; // Task is in the future, stop processing
}
pop_front();

SchedLock();
Comment thread
victor-Lopez25 marked this conversation as resolved.
pop_front();
// mark task as ready
SET_BIT(ready_bitmap_, 1u << candidate_id);

if (task.repeating) [[likely]] {
task.next_fire_us = static_cast<uint32_t>(global_tick_us_ + task.period_us);
insert_sorted(candidate_id);
}
SchedUnlock();
}

schedule_next_interval();
Expand Down
9 changes: 0 additions & 9 deletions Tests/Time/scheduler_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ TEST_F(SchedulerTests, TaskRegistration) {

TEST_F(SchedulerTests, TaskExecutionShort) {
Scheduler::register_task(10, &fake_workload);
Scheduler::start();
TIM2_BASE->PSC = 2; // quicker test

constexpr int NUM_TICKS = 1'000;
Expand All @@ -59,7 +58,6 @@ TEST_F(SchedulerTests, TaskExecutionShort) {

TEST_F(SchedulerTests, TaskExecutionLong) {
Scheduler::register_task(10, &fake_workload);
Scheduler::start();
// TIM2_BASE->ARR = 500;
TIM2_BASE->generate_update();
TIM2_BASE->PSC = 2; // quicker test
Expand All @@ -75,7 +73,6 @@ TEST_F(SchedulerTests, TaskExecutionLong) {

TEST_F(SchedulerTests, SetTimeout) {
Scheduler::set_timeout(10, &fake_workload);
Scheduler::start();
TIM2_BASE->PSC = 2; // quicker test

constexpr int NUM_TICKS = 100;
Expand All @@ -90,7 +87,6 @@ TEST_F(SchedulerTests, SetTimeout) {
TEST_F(SchedulerTests, GlobalTickOverflow) {
Scheduler::global_tick_us_ = 0xFFFFFFF0ULL; // Near 32-bit max
Scheduler::register_task(20, &fake_workload);
Scheduler::start();
TIM2_BASE->PSC = 2; // quicker test

constexpr int NUM_TICKS = 100;
Expand Down Expand Up @@ -133,7 +129,6 @@ TEST_F(SchedulerTests, GlobalTickOverflowManyTasks) {
Scheduler::register_task(10, &multiple_task_1);
Scheduler::register_task(20, &multiple_task_2);
Scheduler::register_task(30, &multiple_task_3);
Scheduler::start();
TIM2_BASE->PSC = 2; // quicker test

constexpr int NUM_TICKS = 100;
Expand All @@ -151,7 +146,6 @@ TEST_F(SchedulerTests, GlobalTickOverflowManyTasks) {

TEST_F(SchedulerTests, TimeoutClearAddTask) {
uint8_t timeout_id = Scheduler::set_timeout(10, &fake_workload);
Scheduler::start();
TIM2_BASE->PSC = 2; // quicker test

constexpr int NUM_TICKS = 100;
Expand Down Expand Up @@ -190,7 +184,6 @@ TEST_F(SchedulerTests, TaskDe_ReRegistration) {
uint8_t connecting_task = Scheduler::register_task(10, &connecting_cyclic);
uint8_t operational_task = 0;
uint8_t fault_task = 0;
Scheduler::start();
TIM2_BASE->PSC = 2; // quicker test

constexpr int NUM_TICKS = 100;
Expand Down Expand Up @@ -231,7 +224,6 @@ TEST_F(SchedulerTests, MultipleTasks) {
Scheduler::register_task(5, &multiple_task_5);
Scheduler::register_task(6, &multiple_task_6);

Scheduler::start();
TIM2_BASE->PSC = 2; // quicker test
constexpr int NUM_TICKS = 300;
for (int i = 0; i < NUM_TICKS; i++) {
Expand All @@ -258,7 +250,6 @@ TEST_F(SchedulerTests, SameTaskMultipleTimes) {
Scheduler::register_task(6, &multiple_task_1);

multiple_task1count = 0;
Scheduler::start();
TIM2_BASE->PSC = 2; // quicker test
constexpr int NUM_TICKS = 300;
for (int i = 0; i < NUM_TICKS; i++) {
Expand Down
Loading