Example
Dependencies: FXAS21002 FXOS8700Q
Diff: simple-mbed-cloud-client/mbed-cloud-client/sal-stack-nanostack-eventloop/nanostack-event-loop/eventOS_event_timer.h
- Revision:
- 0:11cc2b7889af
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/simple-mbed-cloud-client/mbed-cloud-client/sal-stack-nanostack-eventloop/nanostack-event-loop/eventOS_event_timer.h Tue Nov 19 09:49:38 2019 +0000 @@ -0,0 +1,255 @@ +/* + * Copyright (c) 2014-2015 ARM Limited. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef EVENTOS_EVENT_TIMER_H_ +#define EVENTOS_EVENT_TIMER_H_ +#ifdef __cplusplus +extern "C" { +#endif +#include "ns_types.h" +#include "eventOS_event.h" + +struct arm_event_s; +typedef struct sys_timer_struct_s sys_timer_struct_t; + +/* 100 Hz ticker, so 10 milliseconds per tick */ +#define EVENTOS_EVENT_TIMER_HZ 100 + +static inline uint32_t eventOS_event_timer_ticks_to_ms(uint32_t ticks) +{ + NS_STATIC_ASSERT(1000 % EVENTOS_EVENT_TIMER_HZ == 0, "Assuming whole number of ms per tick") + return ticks * (1000 / EVENTOS_EVENT_TIMER_HZ); +} + +/* Convert ms to ticks, rounding up (so 9ms = 1 tick, 10ms = 1 tick, 11ms = 2 ticks) */ +static inline uint32_t eventOS_event_timer_ms_to_ticks(uint32_t ms) +{ + NS_STATIC_ASSERT(1000 % EVENTOS_EVENT_TIMER_HZ == 0, "Assuming whole number of ms per tick") + return (ms + (1000 / EVENTOS_EVENT_TIMER_HZ) - 1) / (1000 / EVENTOS_EVENT_TIMER_HZ); +} + +/** + * Read current timer tick count. + * + * Can be used as a monotonic time source, and to schedule events with + * eventOS_event_timer_send. + * + * Note that the value will wrap, so take care on comparisons. + * + * \return tick count. + */ +extern uint32_t eventOS_event_timer_ticks(void); + +/* Comparison macros handling wrap efficiently (assuming a conventional compiler + * which converts 0x80000000 to 0xFFFFFFFF to negative when casting to int32_t). + */ +#define TICKS_AFTER(a, b) ((int32_t) ((a)-(b)) > 0) +#define TICKS_BEFORE(a, b) ((int32_t) ((a)-(b)) < 0) +#define TICKS_AFTER_OR_AT(a, b) ((int32_t) ((a)-(b)) >= 0) +#define TICKS_BEFORE_OR_AT(a, b) ((int32_t) ((a)-(b)) <= 0) + +/** + * Send an event after time expired (in milliseconds) + * + * Note that the current implementation has the "feature" that rounding + * varies depending on the precise timing requested: + * 0-20 ms => 2 x 10ms tick + * 21-29 ms => 3 x 10ms tick + * 30-39 ms => 4 x 10ms tick + * 40-49 ms => 5 x 10ms tick + * ... etc + * + * For improved flexibility on the event, and for more control of time, + * you should use eventOS_event_timer_request_at(). + * + * \param event_id event_id for event + * \param event_type event_type for event + * \param tasklet_id receiver for event + * \param time time to sleep in milliseconds + * + * \return 0 on success + * \return -1 on error (invalid tasklet_id or allocation failure) + * + * */ +extern int8_t eventOS_event_timer_request(uint8_t event_id, uint8_t event_type, int8_t tasklet_id, uint32_t time); + +/** + * Send an event at specified time + * + * The event will be sent when eventOS_event_timer_ticks() reaches the + * specified value. + * + * If the specified time is in the past (ie "at" is before or at the current + * tick value), the event will be sent immediately. + * + * Can also be invoked using the eventOS_event_send_at() macro in eventOS_event.h + * + * \param event event to send + * \param at absolute tick time to run event at + * + * \return pointer to timer structure on success + * \return NULL on error (invalid tasklet_id or allocation failure) + * + */ +extern arm_event_storage_t *eventOS_event_timer_request_at(const struct arm_event_s *event, uint32_t at); + +/** + * Send an event in a specified time + * + * The event will be sent in the specified number of ticks - to + * be precise, it is equivalent to requesting an event at + * + * eventOS_event_timer_ticks() + ticks + * + * Because of timer granularity, the elapsed time between issuing the request + * and it running may be up to 1 tick less than the specified time. + * + * eg requesting 2 ticks will cause the event to be sent on the second tick from + * now. If requested just after a tick, the delay will be nearly 2 ticks, but if + * requested just before a tick, the delay will be just over 1 tick. + * + * If `in` is <= 0, the event will be sent immediately. + * + * Can also be invoked using the eventOS_event_send_in() macro in eventOS_event.h + * + * \param event event to send + * \param in tick delay for event + * + * \return pointer to timer structure on success + * \return NULL on error (invalid tasklet_id or allocation failure) + * + */ +extern arm_event_storage_t *eventOS_event_timer_request_in(const struct arm_event_s *event, int32_t in); + +/** + * Send an event after a specified time + * + * The event will be sent after the specified number of ticks - to + * be precise, it is equivalent to requesting an event at + * + * eventOS_event_timer_ticks() + ticks + 1 + * + * Because of timer granularity, the elapsed time between issuing the request + * and it running may be up to 1 tick more than the specified time. + * + * eg requesting 2 ticks will cause the event to be sent on the third tick from + * now. If requested just after a tick, the delay will be nearly 3 ticks, but if + * requested just before a tick, the delay will be just over 2 ticks. + * + * If `after` is < 0, the event will be sent immediately. If it is 0, the event + * is sent on the next tick. + * + * Can also be invoked using the eventOS_event_send_after() macro in eventOS_event.h + * + * \param event event to send + * \param after tick delay for event + * + * \return pointer to timer structure on success + * \return NULL on error (invalid tasklet_id or allocation failure) + * + */ +#define eventOS_event_timer_request_after(event, after) \ + eventOS_event_timer_request_in(event, (after) + 1) + +/** + * Send an event periodically + * + * The event will be sent repeatedly using the specified ticks period. + * + * The first call is sent at + * + * eventOS_event_timer_ticks() + ticks + * + * Subsequent events will be sent at N*ticks from the initial time. + * + * Period will be maintained while the device is awake, regardless of delays to + * event scheduling. If an event has not been delivered and completed by the + * next scheduled time, the next event will be sent immediately when it + * finishes. This could cause a continuous stream of events if unable to keep + * up with the period. + * + * Can also be invoked using the eventOS_event_send_every() macro in eventOS_event.h + * + * \param event event to send + * \param period period for event + * + * \return pointer to timer structure on success + * \return NULL on error (invalid tasklet_id or allocation failure) + * + */ +extern arm_event_storage_t *eventOS_event_timer_request_every(const struct arm_event_s *event, int32_t period); + +/** + * Cancel an event timer + * + * This cancels a pending timed event, matched by event_id and tasklet_id. + * + * \param event_id event_id for event + * \param tasklet_id receiver for event + * + * \return 0 on success + * \return -1 on error (event not found) + * + * */ +extern int8_t eventOS_event_timer_cancel(uint8_t event_id, int8_t tasklet_id); + +/** + * System Timer shortest time in milli seconds + * + * \param ticks Time in 10 ms resolution + * + * \return none + * + * */ +extern uint32_t eventOS_event_timer_shortest_active_timer(void); + + +/** Timeout structure. Not to be modified by user */ +typedef struct timeout_entry_t timeout_t; + +/** Request timeout callback. + * + * Create timeout request for specific callback. + * + * \param ms timeout in milliseconds. Maximum range is same as for eventOS_event_timer_request(). + * \param callback function to call after timeout + * \param arg arquement to pass to callback + * \return pointer to timeout structure or NULL on errors + */ +timeout_t *eventOS_timeout_ms(void (*callback)(void *), uint32_t ms, void *arg); + +/** Request periodic callback. + * + * Create timeout request for specific callback. Called periodically until eventOS_timeout_cancel() is called. + * + * \param every period in milliseconds. Maximum range is same as for eventOS_event_timer_request(). + * \param callback function to call after timeout + * \param arg arquement to pass to callback + * \return pointer to timeout structure or NULL on errors + */ +timeout_t *eventOS_timeout_every_ms(void (*callback)(void *), uint32_t every, void *arg); + +/** Cancell timeout request. + * + * \param t timeout request id. + */ +void eventOS_timeout_cancel(timeout_t *t); + + +#ifdef __cplusplus +} +#endif + +#endif /* EVENTOS_EVENT_TIMER_H_ */