From 9a74c6f3c6b26981af050d358506cc2b6afac1fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beat=20K=C3=BCng?= Date: Wed, 8 Sep 2021 12:14:27 +0200 Subject: [PATCH] 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). --- .../src/px4/stm/stm32_common/io_pins/io_timer.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/platforms/nuttx/src/px4/stm/stm32_common/io_pins/io_timer.c b/platforms/nuttx/src/px4/stm/stm32_common/io_pins/io_timer.c index 121ec9629d..23deb5d5b8 100644 --- a/platforms/nuttx/src/px4/stm/stm32_common/io_pins/io_timer.c +++ b/platforms/nuttx/src/px4/stm/stm32_common/io_pins/io_timer.c @@ -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; }