Skip to content

Commit 65bc41a

Browse files
committed
Optimise mbed_ticker_api.c
The generic code in mbed_ticker_api.c uses run-time polymorphism to handle different tickers, and has generic run-time calculations for different ticker widths and frequencies, with a single special-case for 1MHz. Extend the run-time special casing to handle any conversion cases where either the multiply or divide can be done as a shift. This is a speed optimisation for certain platforms. Add a new option `target.custom-tickers`. If turned off, it promises that only USTICKER and LPTICKER devices will be used. This then permits elimination and/or simplification of runtime calculations, saving size and speed. If either both USTICKER and LPTICKER have the same width, or same period numerator or denominator, or only one of them exists, then operations can be hard-coded. This is a significant ROM space saving, and a minor speed and RAM saving. We get to optimise all the calculations, but the run-time polymorphism is retained even if there is only one ticker, as it doesn't significantly affect code size versus direct calls, and the existence of lp_ticker_wrapper and various us_ticker optimisations requires it, even if only LPTICKER is available.
1 parent 6423633 commit 65bc41a

File tree

3 files changed

+283
-70
lines changed

3 files changed

+283
-70
lines changed

hal/include/hal/ticker_api.h

Lines changed: 54 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,22 +70,73 @@ typedef struct {
7070
bool runs_in_deep_sleep; /**< Whether ticker operates in deep sleep */
7171
} ticker_interface_t;
7272

73+
/* Optimizations to avoid run-time computation if custom ticker support is disabled and
74+
* there is exactly one of USTICKER or LPTICKER available, or if they have the same
75+
* parameter value(s).
76+
*/
77+
#define MBED_TICKER_JUST_US (!MBED_CONF_TARGET_CUSTOM_TICKERS && DEVICE_USTICKER && !DEVICE_LPTICKER)
78+
#define MBED_TICKER_JUST_LP (!MBED_CONF_TARGET_CUSTOM_TICKERS && DEVICE_LPTICKER && !DEVICE_USTICKER)
79+
80+
#if (MBED_TICKER_JUST_US && defined US_TICKER_PERIOD_NUM) || \
81+
(!MBED_CONF_TARGET_CUSTOM_TICKERS && defined US_TICKER_PERIOD_NUM && defined LP_TICKER_PERIOD_NUM && \
82+
US_TICKER_PERIOD_NUM == LP_TICKER_PERIOD_NUM)
83+
#define MBED_TICKER_CONSTANT_PERIOD_NUM US_TICKER_PERIOD_NUM
84+
#elif MBED_TICKER_JUST_LP && defined LP_TICKER_PERIOD_NUM
85+
#define MBED_TICKER_CONSTANT_PERIOD_NUM LP_TICKER_PERIOD_NUM
86+
#endif
87+
88+
#if (MBED_TICKER_JUST_US && defined US_TICKER_PERIOD_DEN) || \
89+
(!MBED_CONF_TARGET_CUSTOM_TICKERS && defined US_TICKER_PERIOD_DEN && defined LP_TICKER_PERIOD_DEN && \
90+
US_TICKER_PERIOD_DEN == LP_TICKER_PERIOD_DEN)
91+
#define MBED_TICKER_CONSTANT_PERIOD_DEN US_TICKER_PERIOD_DEN
92+
#elif MBED_TICKER_JUST_LP && defined LP_TICKER_PERIOD_DEN
93+
#define MBED_TICKER_CONSTANT_PERIOD_DEN LP_TICKER_PERIOD_DEN
94+
#endif
95+
96+
#if defined MBED_TICKER_CONSTANT_PERIOD_NUM && defined MBED_TICKER_CONSTANT_PERIOD_DEN
97+
#define MBED_TICKER_CONSTANT_PERIOD
98+
#endif
99+
100+
#if (MBED_TICKER_JUST_US && defined US_TICKER_MASK) || \
101+
(!MBED_CONF_TARGET_CUSTOM_TICKERS && defined US_TICKER_MASK && defined LP_TICKER_MASK && \
102+
US_TICKER_MASK == LP_TICKER_MASK)
103+
#define MBED_TICKER_CONSTANT_MASK US_TICKER_MASK
104+
#elif MBED_TICKER_JUST_LP && defined LP_TICKER_MASK
105+
#define MBED_TICKER_CONSTANT_MASK LP_TICKER_MASK
106+
#endif
107+
73108
/** Ticker's event queue structure
74109
*/
75110
typedef struct {
76111
ticker_event_handler event_handler; /**< Event handler */
77112
ticker_event_t *head; /**< A pointer to head */
78-
uint32_t frequency; /**< Frequency of the timer in Hz */
113+
#ifndef MBED_TICKER_CONSTANT_PERIOD_NUM
114+
uint32_t period_num; /**< Ratio of period to 1us, numerator */
115+
#endif
116+
#ifndef MBED_TICKER_CONSTANT_PERIOD_DEN
117+
uint32_t period_den; /**< Ratio of period to 1us, denominator */
118+
#endif
119+
#ifndef MBED_TICKER_CONSTANT_MASK
79120
uint32_t bitmask; /**< Mask to be applied to time values read */
80121
uint32_t max_delta; /**< Largest delta in ticks that can be used when scheduling */
122+
#endif
123+
#if !(defined MBED_TICKER_CONSTANT_PERIOD && defined MBED_TICKER_CONSTANT_MASK)
81124
uint64_t max_delta_us; /**< Largest delta in us that can be used when scheduling */
125+
#endif
82126
uint32_t tick_last_read; /**< Last tick read */
83-
uint64_t tick_remainder; /**< Ticks that have not been added to base_time */
127+
#if MBED_TICKER_CONSTANT_PERIOD_DEN != 1
128+
uint32_t tick_remainder; /**< Ticks that have not been added to base_time */
129+
#endif
84130
us_timestamp_t present_time; /**< Store the timestamp used for present time */
85131
bool initialized; /**< Indicate if the instance is initialized */
86132
bool dispatching; /**< The function ticker_irq_handler is dispatching */
87133
bool suspended; /**< Indicate if the instance is suspended */
88-
uint8_t frequency_shifts; /**< If frequency is a value of 2^n, this is n, otherwise 0 */
134+
#ifndef MBED_TICKER_CONSTANT_PERIOD_NUM
135+
int8_t period_num_shifts; /**< If numerator is a value of 2^n, this is n, otherwise -1 */
136+
#endif
137+
#ifndef MBED_TICKER_CONSTANT_PERIOD_DEN
138+
int8_t period_den_shifts; /**< If denominator is a value of 2^n, this is n, otherwise -1 */
139+
#endif
89140
} ticker_event_queue_t;
90141

91142
/** Ticker's data structure

0 commit comments

Comments
 (0)