gptimer: fix race condition between start and stop

Added state transition in gptimer_start/stop functions.
So that it's not possible to make a stopped timer continue to run
because of race condition.
This commit is contained in:
morris
2023-03-06 13:32:35 +08:00
parent ed97d230c8
commit 2d52334e5d
11 changed files with 153 additions and 74 deletions

View File

@@ -129,6 +129,7 @@ Start and Stop Timer
^^^^^^^^^^^^^^^^^^^^
The basic IO operation of a timer is to start and stop. Calling :cpp:func:`gptimer_start` can make the internal counter work, while calling :cpp:func:`gptimer_stop` can make the counter stop working. The following illustrates how to start a timer with or without an alarm event.
Calling :cpp:func:`gptimer_start` will transit the driver state from **enable** to **run**, and vice versa. You need to make sure the start and stop functions are used in pairs, otherwise, the functions may return :c:macro:`ESP_ERR_INVALID_STATE`. Most of the time, this error means that the timer is already stopped or in the "start protection" state (i.e. :cpp:func:`gptimer_start` is called but not finished).
Start Timer as a Wall Clock
~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -312,18 +313,15 @@ There is another Kconfig option :ref:`CONFIG_GPTIMER_CTRL_FUNC_IN_IRAM` that can
Thread Safety
^^^^^^^^^^^^^
The factory function :cpp:func:`gptimer_new_timer` is guaranteed to be thread safe by the driver, which means, you can call it from different RTOS tasks without protection by extra locks.
The following functions are allowed to run under ISR context, as the driver uses a critical section to prevent them being called concurrently in the task and ISR.
All the APIs provided by the driver are guaranteed to be thread safe, which means you can call them from different RTOS tasks without protection by extra locks. The following functions are allowed to run under ISR context.
- :cpp:func:`gptimer_start`
- :cpp:func:`gptimer_stop`
- :cpp:func:`gptimer_get_raw_count`
- :cpp:func:`gptimer_set_raw_count`
- :cpp:func:`gptimer_get_captured_count`
- :cpp:func:`gptimer_set_alarm_action`
Other functions that take :cpp:type:`gptimer_handle_t` as the first positional parameter, are not treated as thread safe, which means you should avoid calling them from multiple tasks.
.. _gptimer-kconfig-options:
Kconfig Options

View File

@@ -129,6 +129,7 @@
^^^^^^^^^^^^^^^^
启动和停止是定时器的基本 IO 操作。调用 :cpp:func:`gptimer_start` 可以使内部计数器开始工作,而 :cpp:func:`gptimer_stop` 可以使计数器停止工作。下文说明了如何在存在或不存在警报事件的情况下启动定时器。
调用 :cpp:func:`gptimer_start` 将使驱动程序状态从 enable 转换为 run, 反之亦然。您需要确保 start 和 stop 函数成对使用,否则,函数可能返回 :c:macro:`ESP_ERR_INVALID_STATE`
将定时器作为挂钟启动
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -310,20 +311,17 @@ IRAM 安全
.. _gptimer-thread-safety:
线程安全
^^^^^^^^^^^^^^^^^^
^^^^^^^^
驱动程序会保证工厂函数 :cpp:func:`gptimer_new_timer`线程安全,这意味着您可以从不同的 RTOS 任务中调用这函数,而无需额外的锁保护
由于驱动程序通过使用临界区来防止这些函数在任务和 ISR 中同时被调用,所以以下函数能够在 ISR 上下文中运行。
驱动提供的所有 API 都是线程安全,这意味着您可以从不同的 RTOS 任务中调用这函数,而无需额外的互斥锁去保护。以下这些函数还被允许在中断上下文中运行
- :cpp:func:`gptimer_start`
- :cpp:func:`gptimer_stop`
- :cpp:func:`gptimer_get_raw_count`
- :cpp:func:`gptimer_set_raw_count`
- :cpp:func:`gptimer_get_captured_count`
- :cpp:func:`gptimer_set_alarm_action`
:cpp:type:`gptimer_handle_t` 作为第一个位置参数的其他函数不被视作线程安全,也就是说应该避免从多个任务中调用这些函数。
.. _gptimer-kconfig-options:
Kconfig 选项