stm32: io_timer: lock around io_timer_allocate_channel and io_timer_get_channel_mode

This is to avoid potential race conditions during startup.
All startup code runs sequentially atm, so this is just for robustness
for later (e.g. concurrent pwm_out and dshot start).
This commit is contained in:
Beat Küng 2021-09-08 12:14:27 +02:00 committed by Daniel Agar
parent 847bd120fa
commit 9a74c6f3c6
1 changed files with 10 additions and 5 deletions

View File

@ -437,16 +437,20 @@ static int reallocate_channel_resources(uint32_t channels, io_timer_channel_mode
__EXPORT int io_timer_allocate_channel(unsigned channel, io_timer_channel_mode_t mode)
{
irqstate_t flags = px4_enter_critical_section();
int existing_mode = io_timer_get_channel_mode(channel);
int ret = -EBUSY;
if (existing_mode <= IOTimerChanMode_NotUsed || existing_mode == mode) {
io_timer_channel_allocation_t bit = 1 << channel;
channel_allocations[IOTimerChanMode_NotUsed] &= ~bit;
channel_allocations[mode] |= bit;
return 0;
ret = 0;
}
return -EBUSY;
px4_leave_critical_section(flags);
return ret;
}
@ -785,6 +789,8 @@ int io_timer_channel_init(unsigned channel, io_timer_channel_mode_t mode,
return -EINVAL;
}
irqstate_t flags = px4_enter_critical_section(); // atomic channel allocation and hw config
int previous_mode = io_timer_get_channel_mode(channel);
int rv = allocate_channel(channel, mode);
unsigned timer = channels_timer(channel);
@ -804,8 +810,6 @@ int io_timer_channel_init(unsigned channel, io_timer_channel_mode_t mode,
if (rv == 0) {
irqstate_t flags = px4_enter_critical_section();
/* Set up IO */
if (gpio) {
px4_arch_configgpio(gpio);
@ -854,9 +858,10 @@ int io_timer_channel_init(unsigned channel, io_timer_channel_mode_t mode,
channel_handlers[channel].context = context;
rDIER(timer) |= dier_setbits << shifts;
#endif
px4_leave_critical_section(flags);
}
px4_leave_critical_section(flags);
return rv;
}