mirror of https://github.com/ARMmbed/mbed-os.git
Remove event-loop, to be added as a subtree
parent
8f295177ce
commit
92c284e85d
|
@ -1,6 +0,0 @@
|
|||
*.a
|
||||
output/*
|
||||
build
|
||||
yotta_modules
|
||||
yotta_targets
|
||||
*.lib
|
|
@ -1,32 +0,0 @@
|
|||
# Change Log
|
||||
|
||||
## [mbed-os.5.2-rc1](https://github.com/ARMmbed/sal-stack-nanostack-eventloop/releases/tag/mbed-os.5.2-rc1) (24-Sep-2016)
|
||||
[Full Changelog](https://github.com/ARMmbed/sal-stack-nanostack-eventloop/compare/mbed-os-5.0-rc1...mbed-os.5.2-rc1)
|
||||
|
||||
**New features**
|
||||
|
||||
- Move configuration parameter resolution to separate header and allow user definable configuration header to be used.
|
||||
- Port eventloop system timer to use new tick timer functions platform_tick_timer_register, platform_tick_timer_start and platform_tick_timer_stop.
|
||||
|
||||
**Merged pull requests:**
|
||||
|
||||
commit 283299dbd744c91cb30810ad263798842905c054 (HEAD, tag: mbed-os.5.2-rc1, origin/master, origin/HEAD, master)
|
||||
Author: Jaakko Kukkohovi <jkukkohovi@gmail.com>
|
||||
Date: Fri Sep 23 10:05:55 2016 +0300
|
||||
|
||||
Change configuration method (#23)
|
||||
|
||||
Move configuration parameter resolution to separate header and allow
|
||||
user definable configuration header to be used.
|
||||
|
||||
commit 269b00fba6a637c363f7d1690db0889118bca010
|
||||
Author: Jaakko Kukkohovi <jkukkohovi@gmail.com>
|
||||
Date: Wed Sep 21 11:27:40 2016 +0300
|
||||
|
||||
Systimer using platform tick timer (#22)
|
||||
|
||||
* Port eventloop system timer to use new tick timer functions platform_tick_timer_register, platform_tick_timer_start and platform_tick_timer_stop.Existing functionality is preserved by implementing these functions by default using the high resolution timer as before
|
||||
* New configuration parameter use_platform_tick_timer disables the high resolution timer based tick timer implementation and allows platform to implement the tick timer functions.
|
||||
* New configuration parameter exclude_highres_timer removes the high resolution timer from the build thus providing only eventloop.
|
||||
* Minar support now implemented by providing platform tick timer using minar timers and implicitly using platform tick timers for eventloop when using minar
|
||||
|
|
@ -1,2 +0,0 @@
|
|||
Unless specifically indicated otherwise in a file, files are licensed
|
||||
under the Apache 2.0 license, as can be found in: apache-2.0.txt
|
|
@ -1,56 +0,0 @@
|
|||
|
||||
|
||||
Apache License
|
||||
|
||||
Version 2.0, January 2004
|
||||
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
|
||||
|
||||
You must give any other recipients of the Work or Derivative Works a copy of this License; and
|
||||
You must cause any modified files to carry prominent notices stating that You changed the files; and
|
||||
You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
|
||||
If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
|
@ -1,13 +0,0 @@
|
|||
{
|
||||
"name": "nanostack-eventloop",
|
||||
"config": {
|
||||
"use_platform_tick_timer": {
|
||||
"help": "Use platform provided low resolution tick timer for eventloop",
|
||||
"value": null
|
||||
},
|
||||
"exclude_highres_timer": {
|
||||
"help": "Exclude high resolution timer from build",
|
||||
"value": null
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
{
|
||||
"name": "sal-stack-nanostack-eventloop",
|
||||
"version": "1.1.0",
|
||||
"description": "Event loop for 6LoWPAN stack",
|
||||
"keywords": [],
|
||||
"author": "Seppo Takalo <seppo.takalo@arm.com>",
|
||||
"repository": {
|
||||
"url": "git@github.com:ARMmbed/sal-stack-nanostack-eventloop.git",
|
||||
"type": "git"
|
||||
},
|
||||
"homepage": "https://github.com/ARMmbed/sal-stack-nanostack-eventloop",
|
||||
"license": "Apache-2.0",
|
||||
"extraIncludes": [
|
||||
"nanostack-event-loop"
|
||||
],
|
||||
"dependencies": {
|
||||
"nanostack-libservice": "^3.0.0",
|
||||
"mbed-6lowpan-eventloop-adaptor": "^1.0.0",
|
||||
"minar": "^1.0.0"
|
||||
},
|
||||
"targetDependencies": {}
|
||||
}
|
|
@ -1,32 +0,0 @@
|
|||
/*
|
||||
* 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_CALLBACK_TIMER_H_
|
||||
#define EVENTOS_CALLBACK_TIMER_H_
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#include "ns_types.h"
|
||||
|
||||
extern int8_t eventOS_callback_timer_register(void (*timer_interrupt_handler)(int8_t, uint16_t));
|
||||
extern int8_t eventOS_callback_timer_unregister(int8_t ns_timer_id);
|
||||
|
||||
extern int8_t eventOS_callback_timer_stop(int8_t ns_timer_id);
|
||||
extern int8_t eventOS_callback_timer_start(int8_t ns_timer_id, uint16_t slots);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* EVENTOS_CALLBACK_TIMER_H_ */
|
|
@ -1,74 +0,0 @@
|
|||
/*
|
||||
* 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_H_
|
||||
#define EVENTOS_EVENT_H_
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "ns_types.h"
|
||||
/**
|
||||
* \enum arm_library_event_priority_e
|
||||
* \brief Event Priority level.
|
||||
*/
|
||||
typedef enum arm_library_event_priority_e {
|
||||
ARM_LIB_HIGH_PRIORITY_EVENT = 0, /**< High Priority Event (Function CB) */
|
||||
ARM_LIB_MED_PRIORITY_EVENT = 1, /**< Medium Priority (Timer) */
|
||||
ARM_LIB_LOW_PRIORITY_EVENT = 2, /*!*< Normal Event and ECC / Security */
|
||||
} arm_library_event_priority_e;
|
||||
|
||||
/**
|
||||
* \enum arm_event_s
|
||||
* \brief Event structure.
|
||||
*/
|
||||
typedef struct arm_event_s {
|
||||
int8_t receiver; /**< Event handler Tasklet ID */
|
||||
int8_t sender; /**< Event sender Tasklet ID */
|
||||
uint8_t event_type; /**< This will be typecast arm_library_event_type_e, arm_internal_event_type_e or application specific define */
|
||||
uint8_t event_id; /**< Timer ID, NWK interface ID or application specific ID */
|
||||
void *data_ptr; /**< Application could share data pointer tasklet to tasklet */
|
||||
arm_library_event_priority_e priority;
|
||||
uint32_t event_data;
|
||||
} arm_event_s;
|
||||
|
||||
/**
|
||||
* \brief Send event to event scheduler.
|
||||
*
|
||||
* \param event pointer to pushed event.
|
||||
*
|
||||
* \return 0 Event push OK
|
||||
* \return -1 Memory allocation Fail
|
||||
*
|
||||
*/
|
||||
extern int8_t eventOS_event_send(arm_event_s *event);
|
||||
|
||||
/**
|
||||
* \brief Event handler callback register
|
||||
*
|
||||
* Function will register and allocate unique event id handler
|
||||
*
|
||||
* \param handler_func_ptr function pointer for event handler
|
||||
* \param init_event_type generated evevnt type for init purpose
|
||||
*
|
||||
* \return >= 0 Unique event ID for this handler
|
||||
* \return < 0 Register fail
|
||||
*
|
||||
* */
|
||||
extern int8_t eventOS_event_handler_create(void (*handler_func_ptr)(arm_event_s *), uint8_t init_event_type);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* EVENTOS_EVENT_H_ */
|
|
@ -1,79 +0,0 @@
|
|||
/*
|
||||
* 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"
|
||||
|
||||
/**
|
||||
* Send an event after time expired (in milliseconds)
|
||||
*
|
||||
* \param snmessage event to send
|
||||
* \param time time to sleep in milliseconds
|
||||
*
|
||||
* \return none
|
||||
*
|
||||
* */
|
||||
extern int8_t eventOS_event_timer_request(uint8_t snmessage, uint8_t event_type, int8_t tasklet_id, uint32_t time);
|
||||
/**
|
||||
* Cancel an event
|
||||
*
|
||||
* \param event event to cancel
|
||||
*
|
||||
* \return none
|
||||
*
|
||||
* */
|
||||
extern int8_t eventOS_event_timer_cancel(uint8_t snmessage, 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. Maximum 255 timeouts can be requested.
|
||||
* Not thread safe. Should not be called from interrupt context.
|
||||
* \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);
|
||||
|
||||
/** Cancell timeout request.
|
||||
* Not thread safe. Should not be called from interrupt context.
|
||||
* \param t timeout request id.
|
||||
*/
|
||||
void eventOS_timeout_cancel(timeout_t *t);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* EVENTOS_EVENT_TIMER_H_ */
|
|
@ -1,173 +0,0 @@
|
|||
/*
|
||||
* 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_SCHEDULER_H_
|
||||
#define EVENTOS_SCHEDULER_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#include "ns_types.h"
|
||||
|
||||
/* Compatibility with older ns_types.h */
|
||||
#ifndef NS_NORETURN
|
||||
#define NS_NORETURN
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief Initialise event scheduler.
|
||||
*
|
||||
*/
|
||||
extern void eventOS_scheduler_init(void);
|
||||
|
||||
/**
|
||||
* Process one event from event queue.
|
||||
* Do not call this directly from application. Requires to be public so that simulator can call this.
|
||||
* Use eventOS_scheduler_run() or eventOS_scheduler_run_until_idle().
|
||||
* \return true If there was event processed, false if the event queue was empty.
|
||||
*/
|
||||
bool eventOS_scheduler_dispatch_event(void);
|
||||
|
||||
/**
|
||||
* \brief Process events until no more events to process.
|
||||
*/
|
||||
extern void eventOS_scheduler_run_until_idle(void);
|
||||
|
||||
/**
|
||||
* \brief Start Event scheduler.
|
||||
* Loops forever processing events from the queue.
|
||||
* Calls eventOS_scheduler_idle() whenever event queue is empty.
|
||||
*/
|
||||
NS_NORETURN extern void eventOS_scheduler_run(void);
|
||||
/**
|
||||
* \brief Disable Event scheduler Timers
|
||||
*
|
||||
* \return 0 Timer Stop OK
|
||||
* \return -1 Timer Stop Fail
|
||||
*
|
||||
* */
|
||||
int eventOS_scheduler_timer_stop(void);
|
||||
|
||||
/**
|
||||
* \brief Synch Event scheduler timer after sleep
|
||||
*
|
||||
* \param sleep_ticks time in milli seconds
|
||||
*
|
||||
* \return 0 Timer Synch OK
|
||||
* \return -1 Timer Synch & Start Fail
|
||||
*
|
||||
* */
|
||||
int eventOS_scheduler_timer_synch_after_sleep(uint32_t sleep_ticks);
|
||||
|
||||
/**
|
||||
* \brief Read current active Tasklet ID
|
||||
*
|
||||
* This function not return valid information called inside interrupt
|
||||
*
|
||||
* \return curret active tasklet id
|
||||
*
|
||||
* */
|
||||
extern int8_t eventOS_scheduler_get_active_tasklet(void);
|
||||
|
||||
/**
|
||||
* \brief Set manually Active Tasklet ID
|
||||
*
|
||||
* \param tasklet requested tasklet ID
|
||||
*
|
||||
* */
|
||||
extern void eventOS_scheduler_set_active_tasklet(int8_t tasklet);
|
||||
|
||||
/**
|
||||
* \brief Event scheduler loop idle Callback.
|
||||
|
||||
* Note! This method is called only by eventOS_scheduler_run, needs to be
|
||||
* ported for the platform only if you are using eventOS_scheduler_run().
|
||||
*/
|
||||
extern void eventOS_scheduler_idle(void);
|
||||
|
||||
/**
|
||||
* \brief This function will be called when stack enter idle state and start
|
||||
* waiting signal.
|
||||
*
|
||||
* Note! This method is called only by reference implementation of idle. Needs
|
||||
* to be ported for the platform only if you are using reference implementation.
|
||||
*/
|
||||
extern void eventOS_scheduler_wait(void);
|
||||
|
||||
/**
|
||||
* \brief This function will be called when stack receives an event.
|
||||
*/
|
||||
extern void eventOS_scheduler_signal(void);
|
||||
|
||||
/**
|
||||
* \brief This function will be called when stack can enter deep sleep state in detected time.
|
||||
*
|
||||
* Note! This method is called only by reference implementation of idle. Needs to be
|
||||
* ported for the platform only if you are using reference implementation.
|
||||
*
|
||||
* \param sleep_time_ms Time in milliseconds to sleep
|
||||
* \return time slept in milliseconds
|
||||
*/
|
||||
extern uint32_t eventOS_scheduler_sleep(uint32_t sleep_time_ms);
|
||||
|
||||
/**
|
||||
* \brief Lock a thread against the event loop thread
|
||||
*
|
||||
* This method can be provided by multi-threaded platforms to allow
|
||||
* mutual exclusion with the event loop thread, for cases where
|
||||
* code wants to work with both the event loop and other threads.
|
||||
*
|
||||
* A typical platform implementation would claim the same mutex
|
||||
* before calling eventOS_scheduler_run() or
|
||||
* eventOS_scheduler_dispatch(), and release it during
|
||||
* eventOS_scheduler_idle().
|
||||
*
|
||||
* The mutex must count - nested calls from one thread return
|
||||
* immediately. Thus calling this from inside an event callback
|
||||
* is harmless.
|
||||
*/
|
||||
extern void eventOS_scheduler_mutex_wait(void);
|
||||
|
||||
/**
|
||||
* \brief Release the event loop mutex
|
||||
*
|
||||
* Release the mutex claimed with eventOS_scheduler_mutex_wait(),
|
||||
* allowing the event loop to continue processing.
|
||||
*/
|
||||
extern void eventOS_scheduler_mutex_release(void);
|
||||
|
||||
/**
|
||||
* \brief Check if the current thread owns the event mutex
|
||||
*
|
||||
* Check if the calling thread owns the scheduler mutex.
|
||||
* This allows the ownership to be asserted if a function
|
||||
* requires the mutex to be locked externally.
|
||||
*
|
||||
* The function is only intended as a debugging aid for
|
||||
* users of eventOS_scheduler_mutex_wait() - it is not
|
||||
* used by the event loop core itself.
|
||||
*
|
||||
* If the underlying mutex system does not support it,
|
||||
* this may be implemented to always return true.
|
||||
*
|
||||
* \return true if the current thread owns the mutex
|
||||
*/
|
||||
extern bool eventOS_scheduler_mutex_am_owner(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* EVENTOS_SCHEDULER_H_ */
|
|
@ -1,91 +0,0 @@
|
|||
/*
|
||||
* 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 ARM_HAL_TIMER_H_
|
||||
#define ARM_HAL_TIMER_H_
|
||||
|
||||
#include "eventloop_config.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
/**
|
||||
* \brief This function perform timer init.
|
||||
*/
|
||||
extern void platform_timer_enable(void);
|
||||
|
||||
/**
|
||||
* \brief This function is API for set Timer interrupt handler for stack
|
||||
*
|
||||
* \param new_fp Function pointer for stack giving timer handler
|
||||
*
|
||||
*/
|
||||
typedef void (*platform_timer_cb)(void);
|
||||
extern void platform_timer_set_cb(platform_timer_cb new_fp);
|
||||
|
||||
/**
|
||||
* \brief This function is API for stack timer start
|
||||
*
|
||||
* \param slots define how many 50us slot time period will be started
|
||||
*
|
||||
*/
|
||||
extern void platform_timer_start(uint16_t slots);
|
||||
|
||||
/**
|
||||
* \brief This function is API for stack timer stop
|
||||
*
|
||||
*/
|
||||
extern void platform_timer_disable(void);
|
||||
|
||||
/**
|
||||
* \brief This function is API for stack timer to read active timer remaining slot count
|
||||
*
|
||||
* \return 50us time slot remaining
|
||||
*/
|
||||
extern uint16_t platform_timer_get_remaining_slots(void);
|
||||
|
||||
#ifdef NS_EVENTLOOP_USE_TICK_TIMER
|
||||
/**
|
||||
* \brief This function is API for registering low resolution tick timer callback. Also does
|
||||
* any necessary initialization of the tick timer.
|
||||
*
|
||||
* \return -1 for failure, success otherwise
|
||||
*/
|
||||
extern int8_t platform_tick_timer_register(void (*tick_timer_cb_handler)(void));
|
||||
|
||||
/**
|
||||
* \brief This function is API for starting the low resolution tick timer. The callback
|
||||
* set with platform_tick_timer_register gets called periodically until stopped
|
||||
* by calling platform_tick_timer_stop.
|
||||
*
|
||||
* \param period_ms define how many milliseconds time period will be started
|
||||
* \return -1 for failure, success otherwise
|
||||
*/
|
||||
extern int8_t platform_tick_timer_start(uint32_t period_ms);
|
||||
|
||||
/**
|
||||
* \brief This function is API for stopping the low resolution tick timer
|
||||
*
|
||||
* \return -1 for failure, success otherwise
|
||||
*/
|
||||
extern int8_t platform_tick_timer_stop(void);
|
||||
|
||||
#endif // NS_EVENTLOOP_USE_TICK_TIMER
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* ARM_HAL_TIMER_H_ */
|
|
@ -1,50 +0,0 @@
|
|||
/*
|
||||
* 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 EVENTLOOP_CONFIG_H_
|
||||
#define EVENTLOOP_CONFIG_H_
|
||||
|
||||
/*
|
||||
* Undefine all internal flags before evaluating the configuration
|
||||
*/
|
||||
#undef NS_EVENTLOOP_USE_TICK_TIMER
|
||||
#undef NS_EXCLUDE_HIGHRES_TIMER
|
||||
|
||||
/*
|
||||
* mbedOS 5 specific configuration flag mapping to internal flags
|
||||
*/
|
||||
#ifdef MBED_CONF_NANOSTACK_EVENTLOOP_USE_PLATFORM_TICK_TIMER
|
||||
#define NS_EVENTLOOP_USE_TICK_TIMER 1
|
||||
#endif
|
||||
|
||||
#ifdef MBED_CONF_NANOSTACK_EVENTLOOP_EXCLUDE_HIGHRES_TIMER
|
||||
#define NS_EXCLUDE_HIGHRES_TIMER 1
|
||||
#endif
|
||||
|
||||
/*
|
||||
* For mbedOS 3 and minar use platform tick timer by default, highres timers should come from eventloop adaptor
|
||||
*/
|
||||
#ifdef YOTTA_CFG_MINAR
|
||||
#define NS_EVENTLOOP_USE_TICK_TIMER 1
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Include the user config file if defined
|
||||
*/
|
||||
#ifdef NS_EVENTLOOP_USER_CONFIG_FILE
|
||||
#include NS_EVENTLOOP_USER_CONFIG_FILE
|
||||
#endif
|
||||
|
||||
#endif /* EVENTLOOP_CONFIG_H_ */
|
|
@ -1,321 +0,0 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
#include <string.h>
|
||||
#include "ns_types.h"
|
||||
#include "ns_list.h"
|
||||
#include "eventOS_event.h"
|
||||
#include "eventOS_scheduler.h"
|
||||
#include "timer_sys.h"
|
||||
#include "nsdynmemLIB.h"
|
||||
#include "ns_timer.h"
|
||||
|
||||
#include "platform/arm_hal_interrupt.h"
|
||||
|
||||
|
||||
typedef struct arm_core_tasklet_list_s {
|
||||
int8_t id; /**< Event handler Tasklet ID */
|
||||
void (*func_ptr)(arm_event_s *);
|
||||
ns_list_link_t link;
|
||||
} arm_core_tasklet_list_s;
|
||||
|
||||
typedef struct arm_core_event_s {
|
||||
arm_event_s data;
|
||||
ns_list_link_t link;
|
||||
} arm_core_event_s;
|
||||
|
||||
static NS_LIST_DEFINE(arm_core_tasklet_list, arm_core_tasklet_list_s, link);
|
||||
static NS_LIST_DEFINE(event_queue_active, arm_core_event_s, link);
|
||||
static NS_LIST_DEFINE(free_event_entry, arm_core_event_s, link);
|
||||
|
||||
/** Curr_tasklet tell to core and platform which task_let is active, Core Update this automatic when switch Tasklet. */
|
||||
int8_t curr_tasklet = 0;
|
||||
|
||||
|
||||
static arm_core_tasklet_list_s *tasklet_dynamically_allocate(void);
|
||||
static arm_core_event_s *event_dynamically_allocate(void);
|
||||
static arm_core_event_s *event_core_get(void);
|
||||
static void event_core_write(arm_core_event_s *event);
|
||||
|
||||
static arm_core_tasklet_list_s *event_tasklet_handler_get(uint8_t tasklet_id)
|
||||
{
|
||||
ns_list_foreach(arm_core_tasklet_list_s, cur, &arm_core_tasklet_list) {
|
||||
if (cur->id == tasklet_id) {
|
||||
return cur;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// XXX this can return 0, but 0 seems to mean "none" elsewhere? Or at least
|
||||
// curr_tasklet is reset to 0 in various places.
|
||||
static int8_t tasklet_get_free_id(void)
|
||||
{
|
||||
/*(Note use of uint8_t to avoid overflow if we reach 0x7F)*/
|
||||
for (uint8_t i = 0; i <= INT8_MAX; i++) {
|
||||
if (!event_tasklet_handler_get(i)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int8_t eventOS_event_handler_create(void (*handler_func_ptr)(arm_event_s *), uint8_t init_event_type)
|
||||
{
|
||||
arm_core_event_s *event_tmp;
|
||||
|
||||
// XXX Do we really want to prevent multiple tasklets with same function?
|
||||
ns_list_foreach(arm_core_tasklet_list_s, cur, &arm_core_tasklet_list) {
|
||||
if (cur->func_ptr == handler_func_ptr) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
//Allocate new
|
||||
arm_core_tasklet_list_s *new = tasklet_dynamically_allocate();
|
||||
if (!new) {
|
||||
return -2;
|
||||
}
|
||||
|
||||
event_tmp = event_core_get();
|
||||
if (!event_tmp) {
|
||||
ns_dyn_mem_free(new);
|
||||
return -2;
|
||||
}
|
||||
|
||||
//Fill in tasklet; add to list
|
||||
new->id = tasklet_get_free_id();
|
||||
new->func_ptr = handler_func_ptr;
|
||||
ns_list_add_to_end(&arm_core_tasklet_list, new);
|
||||
|
||||
//Queue "init" event for the new task
|
||||
event_tmp->data.receiver = new->id;
|
||||
event_tmp->data.sender = 0;
|
||||
event_tmp->data.event_type = init_event_type;
|
||||
event_tmp->data.event_data = 0;
|
||||
event_core_write(event_tmp);
|
||||
|
||||
return new->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Send event to event scheduler.
|
||||
*
|
||||
* \param event pointer to pushed event.
|
||||
*
|
||||
* \return 0 Event push OK
|
||||
* \return -1 Memory allocation Fail
|
||||
*
|
||||
*/
|
||||
int8_t eventOS_event_send(arm_event_s *event)
|
||||
{
|
||||
int8_t retval = -1;
|
||||
if (event_tasklet_handler_get(event->receiver)) {
|
||||
arm_core_event_s *event_tmp = event_core_get();
|
||||
if (event_tmp) {
|
||||
event_tmp->data = *event;
|
||||
event_core_write(event_tmp);
|
||||
retval = 0;
|
||||
}
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
static arm_core_event_s *event_dynamically_allocate(void)
|
||||
{
|
||||
return ns_dyn_mem_alloc(sizeof(arm_core_event_s));
|
||||
}
|
||||
|
||||
static arm_core_tasklet_list_s *tasklet_dynamically_allocate(void)
|
||||
{
|
||||
return ns_dyn_mem_alloc(sizeof(arm_core_tasklet_list_s));
|
||||
}
|
||||
|
||||
|
||||
arm_core_event_s *event_core_get(void)
|
||||
{
|
||||
arm_core_event_s *event;
|
||||
platform_enter_critical();
|
||||
event = ns_list_get_first(&free_event_entry);
|
||||
if (event) {
|
||||
ns_list_remove(&free_event_entry, event);
|
||||
} else {
|
||||
event = event_dynamically_allocate();
|
||||
}
|
||||
if (event) {
|
||||
event->data.data_ptr = NULL;
|
||||
event->data.priority = ARM_LIB_LOW_PRIORITY_EVENT;
|
||||
}
|
||||
platform_exit_critical();
|
||||
return event;
|
||||
}
|
||||
|
||||
static void event_core_free_push(arm_core_event_s *free)
|
||||
{
|
||||
platform_enter_critical();
|
||||
ns_list_add_to_start(&free_event_entry, free);
|
||||
platform_exit_critical();
|
||||
}
|
||||
|
||||
|
||||
static arm_core_event_s *event_core_read(void)
|
||||
{
|
||||
arm_core_event_s *event;
|
||||
platform_enter_critical();
|
||||
event = ns_list_get_first(&event_queue_active);
|
||||
if (event) {
|
||||
ns_list_remove(&event_queue_active, event);
|
||||
}
|
||||
platform_exit_critical();
|
||||
return event;
|
||||
}
|
||||
|
||||
void event_core_write(arm_core_event_s *event)
|
||||
{
|
||||
platform_enter_critical();
|
||||
bool added = false;
|
||||
ns_list_foreach(arm_core_event_s, event_tmp, &event_queue_active) {
|
||||
// note enum ordering means we're checking if event_tmp is LOWER priority than event
|
||||
if (event_tmp->data.priority > event->data.priority) {
|
||||
ns_list_add_before(&event_queue_active, event_tmp, event);
|
||||
added = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!added) {
|
||||
ns_list_add_to_end(&event_queue_active, event);
|
||||
}
|
||||
|
||||
/* Wake From Idle */
|
||||
platform_exit_critical();
|
||||
eventOS_scheduler_signal();
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* \brief Initialize Nanostack Core.
|
||||
*
|
||||
* Function Initialize Nanostack Core, Socket Interface,Buffer memory and Send Init event to all Tasklett which are Defined.
|
||||
*
|
||||
*/
|
||||
void eventOS_scheduler_init(void)
|
||||
{
|
||||
/* Reset Event List variables */
|
||||
ns_list_init(&free_event_entry);
|
||||
ns_list_init(&event_queue_active);
|
||||
ns_list_init(&arm_core_tasklet_list);
|
||||
|
||||
//Allocate 10 entry
|
||||
for (uint8_t i = 0; i < 10; i++) {
|
||||
arm_core_event_s *event = event_dynamically_allocate();
|
||||
if (event) {
|
||||
ns_list_add_to_start(&free_event_entry, event);
|
||||
}
|
||||
}
|
||||
|
||||
/* Init Generic timer module */
|
||||
timer_sys_init(); //initialize timer
|
||||
/* Set Tasklett switcher to Idle */
|
||||
curr_tasklet = 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
int8_t eventOS_scheduler_get_active_tasklet(void)
|
||||
{
|
||||
return curr_tasklet;
|
||||
}
|
||||
|
||||
void eventOS_scheduler_set_active_tasklet(int8_t tasklet)
|
||||
{
|
||||
curr_tasklet = tasklet;
|
||||
}
|
||||
|
||||
int eventOS_scheduler_timer_stop(void)
|
||||
{
|
||||
timer_sys_disable();
|
||||
if (ns_timer_sleep() != 0) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int eventOS_scheduler_timer_synch_after_sleep(uint32_t sleep_ticks)
|
||||
{
|
||||
//Update MS to 10ms ticks
|
||||
sleep_ticks /= 10;
|
||||
sleep_ticks++;
|
||||
system_timer_tick_update(sleep_ticks);
|
||||
if (timer_sys_wakeup() == 0) {
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* \brief Infinite Event Read Loop.
|
||||
*
|
||||
* Function Read and handle Cores Event and switch/enable tasklet which are event receiver. WhenEvent queue is empty it goes to sleep
|
||||
*
|
||||
*/
|
||||
bool eventOS_scheduler_dispatch_event(void)
|
||||
{
|
||||
arm_core_tasklet_list_s *tasklet;
|
||||
arm_core_event_s *cur_event;
|
||||
arm_event_s event;
|
||||
|
||||
curr_tasklet = 0;
|
||||
|
||||
cur_event = event_core_read();
|
||||
if (cur_event) {
|
||||
event = cur_event->data;
|
||||
event_core_free_push(cur_event);
|
||||
tasklet = event_tasklet_handler_get(event.receiver);
|
||||
if (tasklet) {
|
||||
curr_tasklet = event.receiver;
|
||||
/* Tasklet Scheduler Call */
|
||||
tasklet->func_ptr(&event);
|
||||
/* Set Current Tasklet to Idle state */
|
||||
curr_tasklet = 0;
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void eventOS_scheduler_run_until_idle(void)
|
||||
{
|
||||
while (eventOS_scheduler_dispatch_event());
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* \brief Infinite Event Read Loop.
|
||||
*
|
||||
* Function Read and handle Cores Event and switch/enable tasklet which are event receiver. WhenEvent queue is empty it goes to sleep
|
||||
*
|
||||
*/
|
||||
NS_NORETURN void eventOS_scheduler_run(void)
|
||||
{
|
||||
while (1) {
|
||||
if (!eventOS_scheduler_dispatch_event()) {
|
||||
eventOS_scheduler_idle();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,71 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2016 ARM Limited, All Rights Reserved
|
||||
*/
|
||||
|
||||
// Include before mbed.h to properly get UINT*_C()
|
||||
|
||||
#include "ns_types.h"
|
||||
|
||||
#include "platform/arm_hal_timer.h"
|
||||
#include "platform/arm_hal_interrupt.h"
|
||||
|
||||
#if defined(NS_EVENTLOOP_USE_TICK_TIMER) && defined(YOTTA_CFG_MINAR)
|
||||
|
||||
#include "minar/minar.h"
|
||||
#include "mbed-drivers/mbed.h"
|
||||
#include "core-util/FunctionPointer.h"
|
||||
#include "core-util/Event.h"
|
||||
|
||||
#define TICK_TIMER_ID 1
|
||||
|
||||
using minar::Scheduler;
|
||||
using minar::milliseconds;
|
||||
using minar::callback_handle_t;
|
||||
using namespace mbed::util;
|
||||
|
||||
static callback_handle_t sys_timer_handle;
|
||||
static void (*tick_timer_callback)(void);
|
||||
|
||||
void timer_callback(void const *funcArgument)
|
||||
{
|
||||
(void)funcArgument;
|
||||
if (NULL != tick_timer_callback) {
|
||||
tick_timer_callback();
|
||||
}
|
||||
}
|
||||
|
||||
// Low precision platform tick timer
|
||||
int8_t platform_tick_timer_register(void (*tick_timer_cb_handler)(void))
|
||||
{
|
||||
tick_timer_callback = tick_timer_cb_handler;
|
||||
return TICK_TIMER_ID;
|
||||
}
|
||||
|
||||
int8_t platform_tick_timer_start(uint32_t period_ms)
|
||||
{
|
||||
int8_t retval = -1;
|
||||
if (sys_timer_handle != NULL) {
|
||||
return 0; // Timer already started already so return success
|
||||
}
|
||||
Event e = FunctionPointer1<void, void const *>(timer_callback).bind(NULL);
|
||||
if (e != NULL) {
|
||||
sys_timer_handle = Scheduler::postCallback(e).period(milliseconds(period_ms)).getHandle();
|
||||
if (sys_timer_handle != NULL) {
|
||||
retval = 0;
|
||||
}
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
int8_t platform_tick_timer_stop(void)
|
||||
{
|
||||
int8_t retval = -1;
|
||||
if (sys_timer_handle != NULL) {
|
||||
Scheduler::cancelCallback(sys_timer_handle);
|
||||
sys_timer_handle = NULL;
|
||||
retval = 0;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
#endif // defined(NS_EVENTLOOP_USE_TICK_TIMER) && defined(YOTTA_CFG)
|
|
@ -1,109 +0,0 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
#include "eventOS_event.h"
|
||||
#include "eventOS_event_timer.h"
|
||||
#include "nsdynmemLIB.h"
|
||||
#include "ns_list.h"
|
||||
|
||||
#define STARTUP_EVENT 0
|
||||
#define TIMER_EVENT 1
|
||||
|
||||
// Timeout structure, already typedefed to timeout_t
|
||||
struct timeout_entry_t {
|
||||
void (*callback)(void *);
|
||||
void *arg;
|
||||
uint8_t event_id;
|
||||
ns_list_link_t link;
|
||||
};
|
||||
|
||||
static NS_LIST_HEAD(timeout_t, link) timeout_list = NS_LIST_INIT(timeout_list);
|
||||
static int8_t timeout_tasklet_id = -1;
|
||||
|
||||
static void timeout_tasklet(arm_event_s *event)
|
||||
{
|
||||
if (TIMER_EVENT != event->event_type) {
|
||||
return;
|
||||
}
|
||||
|
||||
timeout_t *found = NULL;
|
||||
ns_list_foreach_safe(timeout_t, cur, &timeout_list) {
|
||||
if (cur->event_id == event->event_id) {
|
||||
found = cur;
|
||||
ns_list_remove(&timeout_list, cur);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (found) {
|
||||
found->callback(found->arg);
|
||||
ns_dyn_mem_free(found);
|
||||
}
|
||||
}
|
||||
|
||||
timeout_t *eventOS_timeout_ms(void (*callback)(void *), uint32_t ms, void *arg)
|
||||
{
|
||||
uint16_t count;
|
||||
uint8_t index;
|
||||
timeout_t *e = ns_dyn_mem_alloc(sizeof(timeout_t));
|
||||
if (!e) {
|
||||
return NULL;
|
||||
}
|
||||
e->callback = callback;
|
||||
e->arg = arg;
|
||||
|
||||
// Start timeout taskled if it is not running
|
||||
if (-1 == timeout_tasklet_id) {
|
||||
timeout_tasklet_id = eventOS_event_handler_create(timeout_tasklet, STARTUP_EVENT);
|
||||
if (timeout_tasklet_id < 0) {
|
||||
timeout_tasklet_id = -1;
|
||||
goto FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
// Check that we still have indexes left. We have only 8bit timer id.
|
||||
count = ns_list_count(&timeout_list);
|
||||
if (count >= UINT8_MAX) { // Too big list, timer_id is uint8_t
|
||||
goto FAIL;
|
||||
}
|
||||
|
||||
// Find next free index
|
||||
index = 0;
|
||||
AGAIN:
|
||||
ns_list_foreach(timeout_t, cur, &timeout_list) {
|
||||
if (cur->event_id == index) { // This index was used
|
||||
index++; // Check next one.
|
||||
goto AGAIN; // Start checking from begining of the list, indexes are not in order
|
||||
}
|
||||
}
|
||||
e->event_id = index;
|
||||
ns_list_add_to_end(&timeout_list, e);
|
||||
eventOS_event_timer_request(index, TIMER_EVENT, timeout_tasklet_id, ms);
|
||||
return e;
|
||||
FAIL:
|
||||
ns_dyn_mem_free(e);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void eventOS_timeout_cancel(timeout_t *t)
|
||||
{
|
||||
ns_list_foreach_safe(timeout_t, cur, &timeout_list) {
|
||||
if (t == cur) {
|
||||
ns_list_remove(&timeout_list, cur);
|
||||
eventOS_event_timer_cancel(cur->event_id, timeout_tasklet_id);
|
||||
ns_dyn_mem_free(cur);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,392 +0,0 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "ns_types.h"
|
||||
#include "ns_list.h"
|
||||
#include "ns_timer.h"
|
||||
#include "eventOS_callback_timer.h"
|
||||
#include "platform/arm_hal_interrupt.h"
|
||||
#include "platform/arm_hal_timer.h"
|
||||
#include "nsdynmemLIB.h"
|
||||
|
||||
#ifndef NS_EXCLUDE_HIGHRES_TIMER
|
||||
typedef enum ns_timer_state_e {
|
||||
NS_TIMER_ACTIVE = 0, // Will run on the next HAL interrupt
|
||||
NS_TIMER_HOLD, // Will run on a later HAL interrupt
|
||||
NS_TIMER_RUN_INTERRUPT, // Running on the interrupt we're currently handling
|
||||
NS_TIMER_STOP // Timer not scheduled ("start" not called since last callback)
|
||||
} ns_timer_state_e;
|
||||
|
||||
typedef struct ns_timer_struct {
|
||||
int8_t ns_timer_id;
|
||||
ns_timer_state_e timer_state;
|
||||
uint16_t slots;
|
||||
uint16_t remaining_slots;
|
||||
void (*interrupt_handler)(int8_t, uint16_t);
|
||||
ns_list_link_t link;
|
||||
} ns_timer_struct;
|
||||
|
||||
static NS_LIST_DEFINE(ns_timer_list, ns_timer_struct, link);
|
||||
|
||||
|
||||
#define NS_TIMER_RUNNING 1
|
||||
static uint8_t ns_timer_state = 0;
|
||||
|
||||
#ifdef ATMEGA256RFR2
|
||||
#define COMPENSATION 3
|
||||
#define COMPENSATION_TUNE 1
|
||||
#else
|
||||
#define COMPENSATION 0
|
||||
#define COMPENSATION_TUNE 0
|
||||
#endif
|
||||
|
||||
static void ns_timer_interrupt_handler(void);
|
||||
static ns_timer_struct *ns_timer_get_pointer_to_timer_struct(int8_t timer_id);
|
||||
static bool ns_timer_initialized = 0;
|
||||
|
||||
int8_t eventOS_callback_timer_register(void (*timer_interrupt_handler)(int8_t, uint16_t))
|
||||
{
|
||||
int8_t retval = -1;
|
||||
|
||||
if (!ns_timer_initialized) {
|
||||
/*Set interrupt handler in HAL driver*/
|
||||
platform_timer_set_cb(ns_timer_interrupt_handler);
|
||||
ns_timer_initialized = 1;
|
||||
}
|
||||
|
||||
/*Find first free timer ID in timer list*/
|
||||
/*(Note use of uint8_t to avoid overflow if we reach 0x7F)*/
|
||||
for (uint8_t i = 0; i <= INT8_MAX; i++) {
|
||||
if (!ns_timer_get_pointer_to_timer_struct(i)) {
|
||||
retval = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (retval == -1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
ns_timer_struct *new_timer = ns_dyn_mem_alloc(sizeof(ns_timer_struct));
|
||||
if (!new_timer) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*Initialise new timer*/
|
||||
new_timer->ns_timer_id = retval;
|
||||
new_timer->timer_state = NS_TIMER_STOP;
|
||||
new_timer->remaining_slots = 0;
|
||||
new_timer->interrupt_handler = timer_interrupt_handler;
|
||||
|
||||
// Critical section sufficient as long as list can't be reordered from
|
||||
// interrupt, otherwise will need to cover whole routine
|
||||
platform_enter_critical();
|
||||
ns_list_add_to_end(&ns_timer_list, new_timer);
|
||||
platform_exit_critical();
|
||||
|
||||
/*Return timer ID*/
|
||||
return retval;
|
||||
}
|
||||
|
||||
int8_t eventOS_callback_timer_unregister(int8_t ns_timer_id)
|
||||
{
|
||||
ns_timer_struct *current_timer;
|
||||
|
||||
current_timer = ns_timer_get_pointer_to_timer_struct(ns_timer_id);
|
||||
if (!current_timer) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Critical section sufficient as long as list can't be reordered from
|
||||
// interrupt, otherwise will need to cover whole routine
|
||||
platform_enter_critical();
|
||||
ns_list_remove(&ns_timer_list, current_timer);
|
||||
platform_exit_critical();
|
||||
|
||||
ns_dyn_mem_free(current_timer);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int8_t ns_timer_start_pl_timer(uint16_t pl_timer_start_slots)
|
||||
{
|
||||
/*Don't start timer with 0 slots*/
|
||||
if (!pl_timer_start_slots) {
|
||||
pl_timer_start_slots = 1;
|
||||
}
|
||||
|
||||
/*Start HAL timer*/
|
||||
platform_timer_start(pl_timer_start_slots);
|
||||
/*Set HAL timer state to running*/
|
||||
ns_timer_state |= NS_TIMER_RUNNING;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int8_t ns_timer_sleep(void)
|
||||
{
|
||||
int8_t ret_val = -1;
|
||||
if (ns_timer_state & NS_TIMER_RUNNING) {
|
||||
/*Start HAL timer*/
|
||||
platform_timer_disable();
|
||||
/*Set HAL timer state to running*/
|
||||
ns_timer_state &= ~NS_TIMER_RUNNING;
|
||||
ret_val = 0;
|
||||
}
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
static int8_t ns_timer_get_next_running_to(void)
|
||||
{
|
||||
uint8_t hold_count = 0;
|
||||
ns_timer_struct *first_timer = NULL;
|
||||
|
||||
/*Find hold-labelled timer with the least remaining slots*/
|
||||
ns_list_foreach(ns_timer_struct, current_timer, &ns_timer_list) {
|
||||
if (current_timer->timer_state == NS_TIMER_HOLD) {
|
||||
if (!first_timer || current_timer->remaining_slots < first_timer->remaining_slots) {
|
||||
first_timer = current_timer;
|
||||
}
|
||||
/*For optimisation, count the found timers*/
|
||||
hold_count++;
|
||||
}
|
||||
}
|
||||
|
||||
if (!first_timer) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*If hold-labelled timer found, set it active and start the HAL driver*/
|
||||
hold_count--;
|
||||
first_timer->timer_state = NS_TIMER_ACTIVE;
|
||||
/*Compensate time spent in timer function*/
|
||||
if (first_timer->remaining_slots > COMPENSATION) {
|
||||
first_timer->remaining_slots -= COMPENSATION;
|
||||
}
|
||||
/*Start HAL timer*/
|
||||
ns_timer_start_pl_timer(first_timer->remaining_slots);
|
||||
|
||||
/*Update other hold-labelled timers*/
|
||||
ns_list_foreach(ns_timer_struct, current_timer, &ns_timer_list) {
|
||||
if (hold_count == 0) { // early termination optimisation
|
||||
break;
|
||||
}
|
||||
if (current_timer->timer_state == NS_TIMER_HOLD) {
|
||||
if (current_timer->remaining_slots == first_timer->remaining_slots) {
|
||||
current_timer->timer_state = NS_TIMER_ACTIVE;
|
||||
} else {
|
||||
current_timer->remaining_slots -= first_timer->remaining_slots;
|
||||
/*Compensate time spent in timer function*/
|
||||
if (current_timer->remaining_slots > COMPENSATION) {
|
||||
current_timer->remaining_slots -= COMPENSATION;
|
||||
}
|
||||
}
|
||||
hold_count--;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static ns_timer_struct *ns_timer_get_pointer_to_timer_struct(int8_t timer_id)
|
||||
{
|
||||
/*Find timer with the given ID*/
|
||||
ns_list_foreach(ns_timer_struct, current_timer, &ns_timer_list) {
|
||||
if (current_timer->ns_timer_id == timer_id) {
|
||||
return current_timer;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int8_t eventOS_callback_timer_start(int8_t ns_timer_id, uint16_t slots)
|
||||
{
|
||||
int8_t ret_val = 0;
|
||||
uint16_t pl_timer_remaining_slots;
|
||||
ns_timer_struct *timer;
|
||||
platform_enter_critical();
|
||||
|
||||
/*Find timer to be activated*/
|
||||
timer = ns_timer_get_pointer_to_timer_struct(ns_timer_id);
|
||||
if (!timer) {
|
||||
ret_val = -1;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
// XXX this assumes the timer currently isn't running?
|
||||
// Is event.c relying on this restarting HAL timer after ns_timer_sleep()?
|
||||
|
||||
/*If any timers are active*/
|
||||
if (ns_timer_state & NS_TIMER_RUNNING) {
|
||||
/*Get remaining slots of the currently activated timeout*/
|
||||
pl_timer_remaining_slots = platform_timer_get_remaining_slots();
|
||||
|
||||
/*New timeout is shorter than currently enabled timeout*/
|
||||
if (pl_timer_remaining_slots > slots) {
|
||||
/*Start HAL timer*/
|
||||
ns_timer_start_pl_timer(slots - 0);
|
||||
|
||||
ns_list_foreach(ns_timer_struct, current_timer, &ns_timer_list) {
|
||||
/*Switch active timers to hold*/
|
||||
if (current_timer->timer_state == NS_TIMER_ACTIVE) {
|
||||
current_timer->timer_state = NS_TIMER_HOLD;
|
||||
current_timer->remaining_slots = 0;
|
||||
}
|
||||
/*Update hold-labelled timers*/
|
||||
if (current_timer->timer_state == NS_TIMER_HOLD) {
|
||||
current_timer->remaining_slots += (pl_timer_remaining_slots - slots);
|
||||
/*Compensate time spent in timer function*/
|
||||
if (current_timer->remaining_slots > (COMPENSATION - COMPENSATION_TUNE)) {
|
||||
current_timer->remaining_slots -= (COMPENSATION - COMPENSATION_TUNE);
|
||||
}
|
||||
}
|
||||
}
|
||||
/*Mark active and start the timer*/
|
||||
timer->timer_state = NS_TIMER_ACTIVE;
|
||||
timer->slots = slots;
|
||||
timer->remaining_slots = slots;
|
||||
}
|
||||
|
||||
/*New timeout is longer than currently enabled timeout*/
|
||||
else if (pl_timer_remaining_slots < slots) {
|
||||
/*Mark hold and update remaining slots*/
|
||||
timer->timer_state = NS_TIMER_HOLD;
|
||||
timer->slots = slots;
|
||||
timer->remaining_slots = (slots - pl_timer_remaining_slots);
|
||||
}
|
||||
/*New timeout is equal to currently enabled timeout*/
|
||||
else {
|
||||
/*Mark it active and it will be handled in next interrupt*/
|
||||
timer->timer_state = NS_TIMER_ACTIVE;
|
||||
timer->slots = slots;
|
||||
timer->remaining_slots = slots;
|
||||
}
|
||||
} else {
|
||||
/*No timers running*/
|
||||
timer->timer_state = NS_TIMER_HOLD;
|
||||
timer->slots = slots;
|
||||
timer->remaining_slots = slots;
|
||||
/*Start next timeout*/
|
||||
ns_timer_get_next_running_to();
|
||||
}
|
||||
exit:
|
||||
platform_exit_critical();
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
static void ns_timer_interrupt_handler(void)
|
||||
{
|
||||
uint8_t i = 0;
|
||||
|
||||
platform_enter_critical();
|
||||
/*Clear timer running state*/
|
||||
ns_timer_state &= ~NS_TIMER_RUNNING;
|
||||
/*Mark active timers as NS_TIMER_RUN_INTERRUPT, interrupt functions are called at the end of this function*/
|
||||
ns_list_foreach(ns_timer_struct, current_timer, &ns_timer_list) {
|
||||
if (current_timer->timer_state == NS_TIMER_ACTIVE) {
|
||||
current_timer->timer_state = NS_TIMER_RUN_INTERRUPT;
|
||||
/*For optimisation, count the found timers*/
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
/*Start next timeout*/
|
||||
ns_timer_get_next_running_to();
|
||||
|
||||
/*Call interrupt functions*/
|
||||
ns_list_foreach(ns_timer_struct, current_timer, &ns_timer_list) {
|
||||
if (i == 0) {
|
||||
break;
|
||||
}
|
||||
if (current_timer->timer_state == NS_TIMER_RUN_INTERRUPT) {
|
||||
current_timer->timer_state = NS_TIMER_STOP;
|
||||
current_timer->interrupt_handler(current_timer->ns_timer_id, current_timer->slots);
|
||||
i--;
|
||||
}
|
||||
}
|
||||
|
||||
platform_exit_critical();
|
||||
}
|
||||
|
||||
int8_t eventOS_callback_timer_stop(int8_t ns_timer_id)
|
||||
{
|
||||
uint16_t pl_timer_remaining_slots;
|
||||
bool active_timer_found = false;
|
||||
ns_timer_struct *current_timer;
|
||||
ns_timer_struct *first_timer = NULL;
|
||||
int8_t retval = -1;
|
||||
|
||||
platform_enter_critical();
|
||||
/*Find timer with given timer ID*/
|
||||
current_timer = ns_timer_get_pointer_to_timer_struct(ns_timer_id);
|
||||
if (!current_timer) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
retval = 0;
|
||||
|
||||
/*Check if already stopped*/
|
||||
if (current_timer->timer_state == NS_TIMER_STOP) {
|
||||
goto exit;
|
||||
}
|
||||
|
||||
current_timer->timer_state = NS_TIMER_STOP;
|
||||
current_timer->remaining_slots = 0;
|
||||
|
||||
/*Check if some timer is already active*/
|
||||
ns_list_foreach(ns_timer_struct, current_timer, &ns_timer_list) {
|
||||
if (current_timer->timer_state == NS_TIMER_ACTIVE) {
|
||||
active_timer_found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
/*If no active timers found, start one*/
|
||||
if (!active_timer_found) {
|
||||
pl_timer_remaining_slots = platform_timer_get_remaining_slots();
|
||||
/*Find hold-labelled timer with the least remaining slots*/
|
||||
ns_list_foreach(ns_timer_struct, current_timer, &ns_timer_list) {
|
||||
if (current_timer->timer_state == NS_TIMER_HOLD) {
|
||||
current_timer->remaining_slots += pl_timer_remaining_slots;
|
||||
|
||||
if (!first_timer || current_timer->remaining_slots < first_timer->remaining_slots) {
|
||||
first_timer = current_timer;
|
||||
}
|
||||
}
|
||||
}
|
||||
/*If hold-labelled timer found, set it active and start the HAL driver*/
|
||||
if (first_timer) {
|
||||
first_timer->timer_state = NS_TIMER_ACTIVE;
|
||||
/*Start HAL timer*/
|
||||
ns_timer_start_pl_timer(first_timer->remaining_slots);
|
||||
/*If some of the other hold-labelled timers have the same remaining slots as the timer_tmp, mark them active*/
|
||||
ns_list_foreach(ns_timer_struct, current_timer, &ns_timer_list) {
|
||||
if (current_timer->timer_state == NS_TIMER_HOLD) {
|
||||
if (current_timer->remaining_slots == first_timer->remaining_slots) {
|
||||
current_timer->timer_state = NS_TIMER_ACTIVE;
|
||||
} else {
|
||||
current_timer->remaining_slots -= first_timer->remaining_slots;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
exit:
|
||||
platform_exit_critical();
|
||||
|
||||
return retval;
|
||||
}
|
||||
#endif // NS_EXCLUDE_HIGHRES_TIMER
|
|
@ -1,29 +0,0 @@
|
|||
/*
|
||||
* 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 NS_TIMER_H_
|
||||
#define NS_TIMER_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern int8_t ns_timer_sleep(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*NS_TIMER_H_*/
|
|
@ -1,261 +0,0 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
#include "ns_types.h"
|
||||
#include "ns_list.h"
|
||||
#include "timer_sys.h"
|
||||
#include "platform/arm_hal_interrupt.h"
|
||||
#include "platform/arm_hal_timer.h"
|
||||
#include "ns_timer.h"
|
||||
#include "nsdynmemLIB.h"
|
||||
#include "eventOS_event.h"
|
||||
#include "eventOS_callback_timer.h"
|
||||
|
||||
#ifndef ST_MAX
|
||||
#define ST_MAX 6
|
||||
#endif
|
||||
|
||||
typedef struct sys_timer_struct_s {
|
||||
uint32_t timer_sys_launch_time;
|
||||
int8_t timer_sys_launch_receiver;
|
||||
uint8_t timer_sys_launch_message;
|
||||
uint8_t timer_event_type;
|
||||
|
||||
ns_list_link_t link;
|
||||
} sys_timer_struct_s;
|
||||
|
||||
#define TIMER_SLOTS_PER_MS 20
|
||||
#define TIMER_SYS_TICK_PERIOD 10 // milliseconds
|
||||
|
||||
static uint32_t run_time_tick_ticks = 0;
|
||||
static NS_LIST_DEFINE(system_timer_free, sys_timer_struct_s, link);
|
||||
static NS_LIST_DEFINE(system_timer_list, sys_timer_struct_s, link);
|
||||
|
||||
|
||||
static sys_timer_struct_s *sys_timer_dynamically_allocate(void);
|
||||
static void timer_sys_interrupt(void);
|
||||
|
||||
#ifndef NS_EVENTLOOP_USE_TICK_TIMER
|
||||
static int8_t platform_tick_timer_start(uint32_t period_ms);
|
||||
/* Implement platform tick timer using eventOS timer */
|
||||
// platform tick timer callback function
|
||||
static void (*tick_timer_callback)(void);
|
||||
static int8_t tick_timer_id = -1; // eventOS timer id for tick timer
|
||||
|
||||
// EventOS timer callback function
|
||||
static void tick_timer_eventOS_callback(int8_t timer_id, uint16_t slots)
|
||||
{
|
||||
// Not interested in timer id or slots
|
||||
(void)slots;
|
||||
// Call the tick timer callback
|
||||
if (tick_timer_callback != NULL && timer_id == tick_timer_id) {
|
||||
platform_tick_timer_start(TIMER_SYS_TICK_PERIOD);
|
||||
tick_timer_callback();
|
||||
}
|
||||
}
|
||||
|
||||
static int8_t platform_tick_timer_register(void (*tick_timer_cb)(void))
|
||||
{
|
||||
tick_timer_callback = tick_timer_cb;
|
||||
tick_timer_id = eventOS_callback_timer_register(tick_timer_eventOS_callback);
|
||||
return tick_timer_id;
|
||||
}
|
||||
|
||||
static int8_t platform_tick_timer_start(uint32_t period_ms)
|
||||
{
|
||||
return eventOS_callback_timer_start(tick_timer_id, TIMER_SLOTS_PER_MS * period_ms);
|
||||
}
|
||||
|
||||
static int8_t platform_tick_timer_stop(void)
|
||||
{
|
||||
return eventOS_callback_timer_stop(tick_timer_id);
|
||||
}
|
||||
#endif // !NS_EVENTLOOP_USE_TICK_TIMER
|
||||
|
||||
/*
|
||||
* Initializes timers and starts system timer
|
||||
*/
|
||||
void timer_sys_init(void)
|
||||
{
|
||||
run_time_tick_ticks = 0;
|
||||
|
||||
// Clear old timers
|
||||
ns_list_foreach_safe(sys_timer_struct_s, temp, &system_timer_list) {
|
||||
ns_list_remove(&system_timer_list, temp);
|
||||
ns_dyn_mem_free(temp);
|
||||
}
|
||||
// Clear old free timer entrys
|
||||
ns_list_foreach_safe(sys_timer_struct_s, temp, &system_timer_free) {
|
||||
ns_list_remove(&system_timer_free, temp);
|
||||
ns_dyn_mem_free(temp);
|
||||
}
|
||||
|
||||
for (uint8_t i = 0; i < ST_MAX; i++) {
|
||||
sys_timer_struct_s *temp = sys_timer_dynamically_allocate();
|
||||
if (temp) {
|
||||
ns_list_add_to_start(&system_timer_free, temp);
|
||||
}
|
||||
}
|
||||
|
||||
platform_tick_timer_register(timer_sys_interrupt);
|
||||
platform_tick_timer_start(TIMER_SYS_TICK_PERIOD);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-------------------SYSTEM TIMER FUNCTIONS--------------------------*/
|
||||
void timer_sys_disable(void)
|
||||
{
|
||||
platform_tick_timer_stop();
|
||||
}
|
||||
|
||||
/*
|
||||
* Starts ticking system timer interrupts every 10ms
|
||||
*/
|
||||
int8_t timer_sys_wakeup(void)
|
||||
{
|
||||
return platform_tick_timer_start(TIMER_SYS_TICK_PERIOD);
|
||||
}
|
||||
|
||||
|
||||
static void timer_sys_interrupt(void)
|
||||
{
|
||||
system_timer_tick_update(1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* * * * * * * * * */
|
||||
|
||||
static sys_timer_struct_s *sys_timer_dynamically_allocate(void)
|
||||
{
|
||||
return (sys_timer_struct_s*)ns_dyn_mem_alloc(sizeof(sys_timer_struct_s));
|
||||
}
|
||||
|
||||
static sys_timer_struct_s *timer_struct_get(void)
|
||||
{
|
||||
sys_timer_struct_s *timer;
|
||||
platform_enter_critical();
|
||||
timer = ns_list_get_first(&system_timer_free);
|
||||
if (timer) {
|
||||
ns_list_remove(&system_timer_free, timer);
|
||||
} else {
|
||||
timer = sys_timer_dynamically_allocate();
|
||||
}
|
||||
platform_exit_critical();
|
||||
return timer;
|
||||
}
|
||||
|
||||
uint32_t timer_get_runtime_ticks(void) // only used in dev_stats_internal.c
|
||||
{
|
||||
uint32_t ret_val;
|
||||
platform_enter_critical();
|
||||
ret_val = run_time_tick_ticks;
|
||||
platform_exit_critical();
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int8_t eventOS_event_timer_request(uint8_t snmessage, uint8_t event_type, int8_t tasklet_id, uint32_t time)
|
||||
{
|
||||
int8_t res = -1;
|
||||
sys_timer_struct_s *timer = NULL;
|
||||
|
||||
platform_enter_critical();
|
||||
// Note that someone wanting 20ms gets 2 ticks, thanks to this test. 30ms would be 4 ticks.
|
||||
// And why shouldn't they be able to get a 1-tick callback?
|
||||
if (time > 2 * TIMER_SYS_TICK_PERIOD) {
|
||||
time /= TIMER_SYS_TICK_PERIOD;
|
||||
// XXX Why this? Someone wanting 50ms shouldn't get 6 ticks. Round to nearest, maybe?
|
||||
time++;
|
||||
} else {
|
||||
time = 2;
|
||||
}
|
||||
timer = timer_struct_get();
|
||||
if (timer) {
|
||||
timer->timer_sys_launch_message = snmessage;
|
||||
timer->timer_sys_launch_receiver = tasklet_id;
|
||||
timer->timer_event_type = event_type;
|
||||
timer->timer_sys_launch_time = time;
|
||||
ns_list_add_to_start(&system_timer_list, timer);
|
||||
res = 0;
|
||||
}
|
||||
platform_exit_critical();
|
||||
return res;
|
||||
}
|
||||
|
||||
int8_t eventOS_event_timer_cancel(uint8_t snmessage, int8_t tasklet_id)
|
||||
{
|
||||
int8_t res = -1;
|
||||
platform_enter_critical();
|
||||
ns_list_foreach(sys_timer_struct_s, cur, &system_timer_list) {
|
||||
if (cur->timer_sys_launch_receiver == tasklet_id && cur->timer_sys_launch_message == snmessage) {
|
||||
ns_list_remove(&system_timer_list, cur);
|
||||
ns_list_add_to_start(&system_timer_free, cur);
|
||||
res = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
platform_exit_critical();
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
uint32_t eventOS_event_timer_shortest_active_timer(void)
|
||||
{
|
||||
uint32_t ret_val = 0;
|
||||
|
||||
platform_enter_critical();
|
||||
ns_list_foreach(sys_timer_struct_s, cur, &system_timer_list) {
|
||||
if (ret_val == 0 || cur->timer_sys_launch_time < ret_val) {
|
||||
ret_val = cur->timer_sys_launch_time;
|
||||
}
|
||||
}
|
||||
|
||||
platform_exit_critical();
|
||||
//Convert ticks to ms
|
||||
ret_val *= TIMER_SYS_TICK_PERIOD;
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
void system_timer_tick_update(uint32_t ticks)
|
||||
{
|
||||
platform_enter_critical();
|
||||
//Keep runtime time
|
||||
run_time_tick_ticks += ticks;
|
||||
ns_list_foreach_safe(sys_timer_struct_s, cur, &system_timer_list) {
|
||||
if (cur->timer_sys_launch_time <= ticks) {
|
||||
arm_event_s event = {
|
||||
.receiver = cur->timer_sys_launch_receiver,
|
||||
.sender = 0, /**< Event sender Tasklet ID */
|
||||
.data_ptr = NULL,
|
||||
.event_type = cur->timer_event_type,
|
||||
.event_id = cur->timer_sys_launch_message,
|
||||
.event_data = 0,
|
||||
.priority = ARM_LIB_MED_PRIORITY_EVENT,
|
||||
};
|
||||
eventOS_event_send(&event);
|
||||
ns_list_remove(&system_timer_list, cur);
|
||||
ns_list_add_to_start(&system_timer_free, cur);
|
||||
} else {
|
||||
cur->timer_sys_launch_time -= ticks;
|
||||
}
|
||||
}
|
||||
|
||||
platform_exit_critical();
|
||||
}
|
||||
|
|
@ -1,46 +0,0 @@
|
|||
/*
|
||||
* 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 _PL_NANO_TIMER_SYS_H_
|
||||
#define _PL_NANO_TIMER_SYS_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Initialize system timer
|
||||
* */
|
||||
extern void timer_sys_init(void);
|
||||
|
||||
extern uint32_t timer_get_runtime_ticks(void);
|
||||
int8_t timer_sys_wakeup(void);
|
||||
void timer_sys_disable(void);
|
||||
|
||||
/**
|
||||
* System Timer update and synch after sleep
|
||||
*
|
||||
* \param ticks Time in 10 ms resolution
|
||||
*
|
||||
* \return none
|
||||
*
|
||||
* */
|
||||
void system_timer_tick_update(uint32_t ticks);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /*_PL_NANO_TIMER_SYS_H_*/
|
Loading…
Reference in New Issue