mirror of https://github.com/ARMmbed/mbed-os.git
Merge pull request #2804 from yogpan01/mbed-os.5.2-rc1
Updating mbed-client-c and sal-stack-nanostack-eventlooppull/2809/head
commit
98030475af
|
@ -1,5 +1,131 @@
|
|||
# Change Log
|
||||
|
||||
## [v3.0.2](https://github.com/ARMmbed/mbed-client-c/releases/tag/v3.0.2) (24-Sep-2016)
|
||||
[Full Changelog](https://github.com/ARMmbed/mbed-client-c/compare/v3.0.1...v3.0.2)
|
||||
|
||||
**New feature**
|
||||
|
||||
- Make resending flags configurable through Yotta and mbed-cli build systems
|
||||
- Introducing Configuration management through Config file
|
||||
|
||||
**Closed issues:**
|
||||
|
||||
- IOTCLT-882 - Confirmable messages sending
|
||||
|
||||
**Merged pull requests:**
|
||||
|
||||
commit 58f712b9f684bede1905ce35a1a39ebb257c049c (HEAD, tag: v3.0.2, origin/master, origin/HEAD, master)
|
||||
Author: Yogesh Pande <Yogesh.Pande@arm.com>
|
||||
Date: Sat Sep 24 15:04:36 2016 +0300
|
||||
|
||||
version v3.0.2
|
||||
|
||||
commit 39d5e98025f3d8067cea85c4a06470e0e9374812
|
||||
Merge: cf4c119 31d6566
|
||||
Author: Yogesh Pande <yogpan01@users.noreply.github.com>
|
||||
Date: Sat Sep 24 14:51:30 2016 +0300
|
||||
|
||||
Merge pull request #79 from ARMmbed/config-mechanism
|
||||
|
||||
Introducing Configuration management through Config file
|
||||
|
||||
commit 31d6566dddfe449e87819244027b847f53f53a96 (origin/config-mechanism)
|
||||
Author: Yogesh Pande <Yogesh.Pande@arm.com>
|
||||
Date: Sat Sep 24 12:53:47 2016 +0300
|
||||
|
||||
Fixing valgrind with unit tests
|
||||
|
||||
commit a95a90a31e8f6123d14df84688b4e2e2f32e5507
|
||||
Author: Yogesh Pande <Yogesh.Pande@arm.com>
|
||||
Date: Sat Sep 24 12:00:44 2016 +0300
|
||||
|
||||
Fixing valgrind memory leaks for unit tests
|
||||
|
||||
commit 248fc713a4303cb1f724d10f4aa6d68933bb5aed
|
||||
Author: Yogesh Pande <Yogesh.Pande@arm.com>
|
||||
Date: Sat Sep 24 11:32:01 2016 +0300
|
||||
|
||||
Fix for failing unit tests
|
||||
|
||||
commit cec0980b4ccff9708cd0130fea936a69839739b8
|
||||
Merge: cf09b2b cf4c119
|
||||
Author: Yogesh Pande <yogpan01@users.noreply.github.com>
|
||||
Date: Thu Sep 22 18:02:39 2016 +0300
|
||||
|
||||
Merge branch 'master' into config-mechanism
|
||||
|
||||
commit cf4c1196520d64bf863b39efefc663ee60e58c61
|
||||
Merge: 330a16b f5f15cc
|
||||
Author: Antti Yli-Tokola <antti.yli-tokola@arm.com>
|
||||
Date: Thu Sep 22 12:55:33 2016 +0300
|
||||
|
||||
Merge pull request #80 from ARMmbed/revert-77-duplication
|
||||
|
||||
Revert "Enable message duplication by default"
|
||||
|
||||
commit f5f15ccce5fd719aa8d7de14a583d02fd0fd05b9 (origin/revert-77-duplication)
|
||||
Author: Antti Yli-Tokola <antti.yli-tokola@arm.com>
|
||||
Date: Thu Sep 22 12:30:50 2016 +0300
|
||||
|
||||
Revert "Enable message duplication by default"
|
||||
|
||||
commit cf09b2b6233bf897a17bdb0102962947df87f4ae
|
||||
Author: Yogesh Pande <Yogesh.Pande@arm.com>
|
||||
Date: Thu Sep 22 09:57:41 2016 +0300
|
||||
|
||||
Fixed comments from PR#79
|
||||
|
||||
This commit includes
|
||||
- Fixing comments from PR-79
|
||||
|
||||
commit 8fd7cc258168047c29aca27a659de448f45e0e6f
|
||||
Author: Yogesh Pande <Yogesh.Pande@arm.com>
|
||||
Date: Wed Sep 21 20:42:28 2016 +0300
|
||||
|
||||
Introducing Configuration management through Config file
|
||||
|
||||
This commit includes
|
||||
- Support for configuring various build time parameters throuh user supplied config file
|
||||
that can be passed at compile time through Makefile system which will work for
|
||||
non mbed-OS and non yotta build system as well.
|
||||
|
||||
commit 330a16bbfc5dc597015c7bdd935b603282d7064e
|
||||
Merge: b7d909e e268081
|
||||
Author: Antti Yli-Tokola <antti.yli-tokola@arm.com>
|
||||
Date: Wed Sep 21 12:05:29 2016 +0300
|
||||
|
||||
Merge pull request #78 from ARMmbed/resend_flags
|
||||
|
||||
Make resend flags configurable through Yotta and mbed-cli build sy…
|
||||
|
||||
commit e268081bae1fa1db3b5b64dfb77d5b7a5bfed748
|
||||
Merge: dc16b29 b7d909e
|
||||
Author: Antti Yli-Tokola <antti.yli-tokola@arm.com>
|
||||
Date: Wed Sep 21 12:02:32 2016 +0300
|
||||
|
||||
Merge branch 'master' into resend_flags
|
||||
|
||||
commit b7d909eca1c2259453dbe9c094b8a0c53d638fea
|
||||
Merge: 7f0eaea ad3b468
|
||||
Author: Antti Yli-Tokola <antti.yli-tokola@arm.com>
|
||||
Date: Wed Sep 21 12:02:15 2016 +0300
|
||||
|
||||
Merge pull request #77 from ARMmbed/duplication
|
||||
|
||||
Enable message duplication by default
|
||||
|
||||
commit dc16b299ab9ff4bd1eaa9d3ec120fa58180820c4
|
||||
Author: Antti Yli-Tokola <antti.yli-tokola@arm.com>
|
||||
Date: Mon Sep 19 14:35:31 2016 +0300
|
||||
|
||||
Make resending flags configurable through Yotta and mbed-cli build systems
|
||||
|
||||
commit ad3b46881bb61dfc2510d13d373bcd1faad114f4
|
||||
Author: Antti Yli-Tokola <antti.yli-tokola@arm.com>
|
||||
Date: Fri Sep 16 08:58:38 2016 +0300
|
||||
|
||||
Enable message duplication by default
|
||||
|
||||
## [v3.0.1](https://github.com/ARMmbed/mbed-client-c/releases/tag/v3.0.1) (15-Sep-2016)
|
||||
[Full Changelog](https://github.com/ARMmbed/mbed-client-c/compare/mbed-os-5.0-rc1...v3.0.1)
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "mbed-client-c",
|
||||
"version": "3.0.1",
|
||||
"version": "3.0.2",
|
||||
"description": "Nanostack NSDL and COAP library",
|
||||
"keywords": [
|
||||
"coap",
|
||||
|
|
|
@ -0,0 +1,90 @@
|
|||
/*
|
||||
* Copyright (c) 2016 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 SN_CONFIG_H
|
||||
#define SN_CONFIG_H
|
||||
|
||||
/**
|
||||
* \brief Configuration options (set of defines and values)
|
||||
*
|
||||
* This lists set of compile-time options that needs to be used to enable
|
||||
* or disable features selectively, and set the values for the mandatory
|
||||
* parameters.
|
||||
*/
|
||||
|
||||
/**
|
||||
* \def SN_COAP_DUPLICATION_MAX_MSGS_COUNT
|
||||
* \brief For Message duplication detection
|
||||
* Init value for the maximum count of messages to be stored for duplication detection
|
||||
* Setting of this value to 0 will disable duplication check, also reduce use of ROM memory
|
||||
* Default is set to 1.
|
||||
*/
|
||||
#undef SN_COAP_DUPLICATION_MAX_MSGS_COUNT /* 1 */
|
||||
|
||||
/**
|
||||
* \def SN_COAP_MAX_BLOCKWISE_PAYLOAD_SIZE
|
||||
*
|
||||
* \brief For Message blockwising
|
||||
* Init value for the maximum payload size to be sent and received at one blockwise message
|
||||
* Setting of this value to 0 will disable this feature, and also reduce use of ROM memory
|
||||
* Note: This define is common for both received and sent Blockwise messages
|
||||
*/
|
||||
#undef SN_COAP_MAX_BLOCKWISE_PAYLOAD_SIZE /* 0 */ // < Must be 2^x and x is at least 4. Suitable values: 0, 16, 32, 64, 128, 256, 512 and 1024
|
||||
|
||||
/**
|
||||
* \def COAP_DISABLE_OBS_FEATURE
|
||||
*
|
||||
* \brief Disables CoAP 'obs' sending feature
|
||||
* as part of registration message, this might be
|
||||
* needed to be enabled for some strict LWM2M server implementation.
|
||||
* By default, this feature is disabled.
|
||||
*/
|
||||
#undef COAP_DISABLE_OBS_FEATURE
|
||||
|
||||
/**
|
||||
* \def SN_COAP_RESENDING_QUEUE_SIZE_MSGS
|
||||
*
|
||||
* \brief Sets the number of messages stored
|
||||
* in the resending queue. Default is 2
|
||||
*/
|
||||
#undef SN_COAP_RESENDING_QUEUE_SIZE_MSGS /* 2 */ // < Default re-sending queue size - defines how many messages can be stored. Setting this to 0 disables feature
|
||||
|
||||
/**
|
||||
* \def SN_COAP_RESENDING_QUEUE_SIZE_BYTES
|
||||
*
|
||||
* \brief Sets the size of the re-sending buffer.
|
||||
* Setting this to 0 disables this feature.
|
||||
* By default, this feature is disabled.
|
||||
*/
|
||||
#undef SN_COAP_RESENDING_QUEUE_SIZE_BYTES /* 0 */ // Default re-sending queue size - defines size of the re-sending buffer. Setting this to 0 disables feature
|
||||
|
||||
/**
|
||||
* \def SN_COAP_MAX_INCOMING_MESSAGE_SIZE
|
||||
*
|
||||
* \brief Sets the maximum size (in bytes) that
|
||||
* mbed Client will allow to be handled while
|
||||
* receiving big payload in blockwise mode.
|
||||
* Application can set this value based on their
|
||||
* available storage capability.
|
||||
* By default, maximum size is UINT16_MAX, 65535 bytes.
|
||||
*/
|
||||
#undef SN_COAP_MAX_INCOMING_MESSAGE_SIZE /* UINT16_MAX */
|
||||
|
||||
#ifdef MBED_CLIENT_USER_CONFIG_FILE
|
||||
#include MBED_CLIENT_USER_CONFIG_FILE
|
||||
#endif
|
||||
|
||||
#endif // SN_CONFIG_H
|
0
features/FEATURE_COMMON_PAL/mbed-client-c/run_unit_tests_with_valgrind.sh
Normal file → Executable file
0
features/FEATURE_COMMON_PAL/mbed-client-c/run_unit_tests_with_valgrind.sh
Normal file → Executable file
|
@ -26,6 +26,7 @@
|
|||
|
||||
#include "ns_list.h"
|
||||
#include "sn_coap_header_internal.h"
|
||||
#include "sn_config.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
@ -41,8 +42,27 @@ struct sn_coap_hdr_;
|
|||
#define ENABLE_RESENDINGS 1 /**< Enable / Disable resending from library in building */
|
||||
|
||||
#define SN_COAP_RESENDING_MAX_COUNT 3 /**< Default number of re-sendings */
|
||||
|
||||
#ifdef YOTTA_CFG_COAP_RESENDING_QUEUE_SIZE_MSGS
|
||||
#define SN_COAP_RESENDING_QUEUE_SIZE_MSGS YOTTA_CFG_COAP_RESENDING_QUEUE_SIZE_MSGS
|
||||
#elif defined MBED_CONF_MBED_CLIENT_SN_COAP_RESENDING_QUEUE_SIZE_MSGS
|
||||
#define SN_COAP_RESENDING_QUEUE_SIZE_MSGS MBED_CONF_MBED_CLIENT_SN_COAP_RESENDING_QUEUE_SIZE_MSGS
|
||||
#endif
|
||||
|
||||
#ifndef SN_COAP_RESENDING_QUEUE_SIZE_MSGS
|
||||
#define SN_COAP_RESENDING_QUEUE_SIZE_MSGS 2 /**< Default re-sending queue size - defines how many messages can be stored. Setting this to 0 disables feature */
|
||||
#endif
|
||||
|
||||
#ifdef YOTTA_CFG_COAP_RESENDING_QUEUE_SIZE_BYTES
|
||||
#define SN_COAP_RESENDING_QUEUE_SIZE_BYTES YOTTA_CFG_COAP_RESENDING_QUEUE_SIZE_BYTES
|
||||
#elif defined MBED_CONF_MBED_CLIENT_SN_COAP_RESENDING_QUEUE_SIZE_BYTES
|
||||
#define SN_COAP_RESENDING_QUEUE_SIZE_BYTES MBED_CONF_MBED_CLIENT_SN_COAP_RESENDING_QUEUE_SIZE_BYTES
|
||||
#endif
|
||||
|
||||
#ifndef SN_COAP_RESENDING_QUEUE_SIZE_BYTES
|
||||
#define SN_COAP_RESENDING_QUEUE_SIZE_BYTES 0 /**< Default re-sending queue size - defines size of the re-sending buffer. Setting this to 0 disables feature */
|
||||
#endif
|
||||
|
||||
#define DEFAULT_RESPONSE_TIMEOUT 10 /**< Default re-sending timeout as seconds */
|
||||
|
||||
/* These parameters sets maximum values application can set with API */
|
||||
|
@ -81,7 +101,6 @@ struct sn_coap_hdr_;
|
|||
|
||||
/* Init value for the maximum payload size to be sent and received at one blockwise message */
|
||||
/* Setting of this value to 0 will disable this feature, and also reduce use of ROM memory */
|
||||
/* Note: Current Coap implementation supports Blockwise transfers specification version draft-ietf-core-block-03 */
|
||||
/* Note: This define is common for both received and sent Blockwise messages */
|
||||
|
||||
#ifdef YOTTA_CFG_COAP_MAX_BLOCKWISE_PAYLOAD_SIZE
|
||||
|
|
0
features/FEATURE_COMMON_PAL/mbed-client-c/source/libNsdl/src/include/sn_grs.h
Normal file → Executable file
0
features/FEATURE_COMMON_PAL/mbed-client-c/source/libNsdl/src/include/sn_grs.h
Normal file → Executable file
0
features/FEATURE_COMMON_PAL/mbed-client-c/source/libNsdl/src/sn_grs.c
Normal file → Executable file
0
features/FEATURE_COMMON_PAL/mbed-client-c/source/libNsdl/src/sn_grs.c
Normal file → Executable file
1
features/FEATURE_COMMON_PAL/mbed-client-c/source/libNsdl/src/sn_nsdl.c
Normal file → Executable file
1
features/FEATURE_COMMON_PAL/mbed-client-c/source/libNsdl/src/sn_nsdl.c
Normal file → Executable file
|
@ -29,6 +29,7 @@
|
|||
#include "sn_coap_protocol_internal.h"
|
||||
#include "sn_nsdl_lib.h"
|
||||
#include "sn_grs.h"
|
||||
#include "sn_config.h"
|
||||
#include "mbed-trace/mbed_trace.h"
|
||||
|
||||
#define TRACE_GROUP "coap"
|
||||
|
|
0
features/FEATURE_COMMON_PAL/mbed-client-c/test/multithread-linux-test/tester.sh
Normal file → Executable file
0
features/FEATURE_COMMON_PAL/mbed-client-c/test/multithread-linux-test/tester.sh
Normal file → Executable file
0
features/FEATURE_COMMON_PAL/mbed-client-c/test/nsdl-c/unittest/MakefileWorker.mk
Normal file → Executable file
0
features/FEATURE_COMMON_PAL/mbed-client-c/test/nsdl-c/unittest/MakefileWorker.mk
Normal file → Executable file
0
features/FEATURE_COMMON_PAL/mbed-client-c/test/nsdl-c/unittest/makefile_defines.txt
Normal file → Executable file
0
features/FEATURE_COMMON_PAL/mbed-client-c/test/nsdl-c/unittest/makefile_defines.txt
Normal file → Executable file
0
features/FEATURE_COMMON_PAL/mbed-client-c/test/nsdl-c/unittest/run_tests
Normal file → Executable file
0
features/FEATURE_COMMON_PAL/mbed-client-c/test/nsdl-c/unittest/run_tests
Normal file → Executable file
|
@ -27,6 +27,7 @@
|
|||
#include "sn_coap_parser_stub.h"
|
||||
#include "sn_coap_header_check_stub.h"
|
||||
|
||||
|
||||
int retCounter = 0;
|
||||
static coap_s *coap_handle = NULL;
|
||||
void myFree(void* addr);
|
||||
|
@ -87,9 +88,13 @@ TEST(libCoap_protocol, sn_coap_protocol_destroy)
|
|||
msg_ptr->send_msg_ptr->uri_path_len = 2;
|
||||
|
||||
ns_list_add_to_end(&handle->linked_list_resent_msgs, msg_ptr);
|
||||
#if SN_COAP_DUPLICATION_MAX_MSGS_COUNT
|
||||
ns_list_init(&handle->linked_list_duplication_msgs);
|
||||
#endif
|
||||
#if SN_COAP_MAX_BLOCKWISE_PAYLOAD_SIZE
|
||||
ns_list_init(&handle->linked_list_blockwise_sent_msgs);
|
||||
ns_list_init(&handle->linked_list_blockwise_received_payloads);
|
||||
#endif
|
||||
CHECK( 0 == sn_coap_protocol_destroy(handle));
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
#ifndef TEST_CONFIG_H
|
||||
#define TEST_CONFIG_H
|
||||
|
||||
/**
|
||||
* \def SN_COAP_DUPLICATION_MAX_MSGS_COUNT
|
||||
* \brief For Message duplication detection
|
||||
* Init value for the maximum count of messages to be stored for duplication detection
|
||||
* Setting of this value to 0 will disable duplication check, also reduce use of ROM memory
|
||||
* Default is set to 0.
|
||||
*/
|
||||
#define SN_COAP_DUPLICATION_MAX_MSGS_COUNT 1
|
||||
|
||||
#endif
|
0
features/FEATURE_COMMON_PAL/mbed-client-c/test/nsdl-c/unittest/stubs/sn_grs_stub.c
Normal file → Executable file
0
features/FEATURE_COMMON_PAL/mbed-client-c/test/nsdl-c/unittest/stubs/sn_grs_stub.c
Normal file → Executable file
0
features/FEATURE_COMMON_PAL/mbed-client-c/test/nsdl-c/unittest/stubs/sn_nsdl_stub.c
Normal file → Executable file
0
features/FEATURE_COMMON_PAL/mbed-client-c/test/nsdl-c/unittest/stubs/sn_nsdl_stub.c
Normal file → Executable file
|
@ -1 +0,0 @@
|
|||
source/*
|
|
@ -0,0 +1,32 @@
|
|||
# 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,322 +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 */
|
||||
ns_timer_init();
|
||||
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,389 +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"
|
||||
|
||||
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);
|
||||
|
||||
int8_t ns_timer_init(void)
|
||||
{
|
||||
/*Set interrupt handler in HAL driver*/
|
||||
platform_timer_set_cb(ns_timer_interrupt_handler);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int8_t eventOS_callback_timer_register(void (*timer_interrupt_handler)(int8_t, uint16_t))
|
||||
{
|
||||
int8_t retval = -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;
|
||||
}
|
|
@ -1,22 +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_
|
||||
|
||||
extern int8_t ns_timer_init(void);
|
||||
extern int8_t ns_timer_sleep(void);
|
||||
|
||||
#endif /*NS_TIMER_H_*/
|
|
@ -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,38 +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_
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
#endif /*_PL_NANO_TIMER_SYS_H_*/
|
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
"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
|
||||
}
|
||||
}
|
||||
}
|
|
@ -15,6 +15,9 @@
|
|||
*/
|
||||
#ifndef ARM_HAL_TIMER_H_
|
||||
#define ARM_HAL_TIMER_H_
|
||||
|
||||
#include "eventloop_config.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
@ -22,6 +25,7 @@ extern "C" {
|
|||
* \brief This function perform timer init.
|
||||
*/
|
||||
extern void platform_timer_enable(void);
|
||||
|
||||
/**
|
||||
* \brief This function is API for set Timer interrupt handler for stack
|
||||
*
|
||||
|
@ -30,6 +34,7 @@ extern void platform_timer_enable(void);
|
|||
*/
|
||||
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
|
||||
*
|
||||
|
@ -37,17 +42,48 @@ extern void platform_timer_set_cb(platform_timer_cb new_fp);
|
|||
*
|
||||
*/
|
||||
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
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* 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_ */
|
|
@ -228,7 +228,6 @@ void eventOS_scheduler_init(void)
|
|||
}
|
||||
|
||||
/* Init Generic timer module */
|
||||
ns_timer_init();
|
||||
timer_sys_init(); //initialize timer
|
||||
/* Set Tasklett switcher to Idle */
|
||||
curr_tasklet = 0;
|
||||
|
|
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* 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)
|
|
@ -13,6 +13,7 @@
|
|||
* 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"
|
||||
|
@ -21,6 +22,7 @@
|
|||
#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
|
||||
|
@ -53,18 +55,18 @@ static uint8_t ns_timer_state = 0;
|
|||
|
||||
static void ns_timer_interrupt_handler(void);
|
||||
static ns_timer_struct *ns_timer_get_pointer_to_timer_struct(int8_t timer_id);
|
||||
|
||||
int8_t ns_timer_init(void)
|
||||
{
|
||||
/*Set interrupt handler in HAL driver*/
|
||||
platform_timer_set_cb(ns_timer_interrupt_handler);
|
||||
return 0;
|
||||
}
|
||||
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++) {
|
||||
|
@ -374,6 +376,8 @@ int8_t eventOS_callback_timer_stop(int8_t ns_timer_id)
|
|||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -385,3 +389,4 @@ exit:
|
|||
|
||||
return retval;
|
||||
}
|
||||
#endif // NS_EXCLUDE_HIGHRES_TIMER
|
||||
|
|
|
@ -20,7 +20,6 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern int8_t ns_timer_init(void);
|
||||
extern int8_t ns_timer_sleep(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#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"
|
||||
|
@ -35,19 +36,53 @@ typedef struct sys_timer_struct_s {
|
|||
ns_list_link_t link;
|
||||
} sys_timer_struct_s;
|
||||
|
||||
#define TIMER_SLOTS_PER_MS 20
|
||||
#define TIMER_SYS_TICK_PERIOD 10 // milliseconds
|
||||
#define TIMER_SYS_TICK_SLOTS (TIMER_SYS_TICK_PERIOD * 20) // 50us slots
|
||||
|
||||
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 int8_t sys_timer_id = -1;
|
||||
|
||||
|
||||
static sys_timer_struct_s *sys_timer_dynamically_allocate(void);
|
||||
static void timer_sys_interrupt(int8_t timer_id, uint16_t slots);
|
||||
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
|
||||
|
@ -56,8 +91,6 @@ void timer_sys_init(void)
|
|||
{
|
||||
run_time_tick_ticks = 0;
|
||||
|
||||
sys_timer_id = eventOS_callback_timer_register(timer_sys_interrupt);
|
||||
|
||||
// Clear old timers
|
||||
ns_list_foreach_safe(sys_timer_struct_s, temp, &system_timer_list) {
|
||||
ns_list_remove(&system_timer_list, temp);
|
||||
|
@ -76,9 +109,8 @@ void timer_sys_init(void)
|
|||
}
|
||||
}
|
||||
|
||||
if (sys_timer_id >= 0) {
|
||||
eventOS_callback_timer_start(sys_timer_id, TIMER_SYS_TICK_SLOTS);
|
||||
}
|
||||
platform_tick_timer_register(timer_sys_interrupt);
|
||||
platform_tick_timer_start(TIMER_SYS_TICK_PERIOD);
|
||||
}
|
||||
|
||||
|
||||
|
@ -86,7 +118,7 @@ void timer_sys_init(void)
|
|||
/*-------------------SYSTEM TIMER FUNCTIONS--------------------------*/
|
||||
void timer_sys_disable(void)
|
||||
{
|
||||
eventOS_callback_timer_stop(sys_timer_id);
|
||||
platform_tick_timer_stop();
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -94,20 +126,12 @@ void timer_sys_disable(void)
|
|||
*/
|
||||
int8_t timer_sys_wakeup(void)
|
||||
{
|
||||
int8_t ret_val = -1;
|
||||
if (sys_timer_id >= 0) {
|
||||
ret_val = eventOS_callback_timer_start(sys_timer_id, TIMER_SYS_TICK_SLOTS);
|
||||
}
|
||||
return ret_val;
|
||||
return platform_tick_timer_start(TIMER_SYS_TICK_PERIOD);
|
||||
}
|
||||
|
||||
|
||||
static void timer_sys_interrupt(int8_t timer_id, uint16_t slots)
|
||||
static void timer_sys_interrupt(void)
|
||||
{
|
||||
(void)timer_id;
|
||||
(void)slots;
|
||||
eventOS_callback_timer_start(sys_timer_id, TIMER_SYS_TICK_SLOTS);
|
||||
|
||||
system_timer_tick_update(1);
|
||||
}
|
||||
|
||||
|
@ -117,7 +141,7 @@ static void timer_sys_interrupt(int8_t timer_id, uint16_t slots)
|
|||
|
||||
static sys_timer_struct_s *sys_timer_dynamically_allocate(void)
|
||||
{
|
||||
return ns_dyn_mem_alloc(sizeof(sys_timer_struct_s));
|
||||
return (sys_timer_struct_s*)ns_dyn_mem_alloc(sizeof(sys_timer_struct_s));
|
||||
}
|
||||
|
||||
static sys_timer_struct_s *timer_struct_get(void)
|
|
@ -1,234 +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 "ns_timer.h"
|
||||
#include "nsdynmemLIB.h"
|
||||
#include "eventOS_event.h"
|
||||
#include "eventOS_event_timer.h"
|
||||
#include "minar/minar.h"
|
||||
#include "mbed.h"
|
||||
#include "core-util/FunctionPointer.h"
|
||||
#include "core-util/Event.h"
|
||||
|
||||
using minar::Scheduler;
|
||||
using minar::milliseconds;
|
||||
using minar::callback_handle_t;
|
||||
using namespace mbed::util;
|
||||
|
||||
#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_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 callback_handle_t sys_timer_handle;
|
||||
|
||||
|
||||
static sys_timer_struct_s *sys_timer_dynamically_allocate(void);
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* 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);
|
||||
}
|
||||
}
|
||||
|
||||
Event e = FunctionPointer1<void, uint32_t>(system_timer_tick_update).bind(1);
|
||||
sys_timer_handle = Scheduler::postCallback(e).period(milliseconds(TIMER_SYS_TICK_PERIOD)).getHandle();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*-------------------SYSTEM TIMER FUNCTIONS--------------------------*/
|
||||
void timer_sys_disable(void)
|
||||
{
|
||||
if (sys_timer_handle != NULL) {
|
||||
Scheduler::cancelCallback(sys_timer_handle);
|
||||
sys_timer_handle = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Starts ticking system timer interrupts every 10ms
|
||||
*/
|
||||
int8_t timer_sys_wakeup(void)
|
||||
{
|
||||
// postCallback should never fail in MINAR
|
||||
// TODO: check if that's true
|
||||
if (NULL == sys_timer_handle) {
|
||||
Event e = FunctionPointer1<void, uint32_t>(system_timer_tick_update).bind(1);
|
||||
sys_timer_handle = Scheduler::postCallback(e).tolerance(minar::milliseconds(TIMER_SYS_TICK_PERIOD/10)).period(milliseconds(TIMER_SYS_TICK_PERIOD)).getHandle();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* * * * * * * * * */
|
||||
|
||||
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;
|
||||
event.receiver = cur->timer_sys_launch_receiver;
|
||||
event.sender = 0; /**< Event sender Tasklet ID */
|
||||
event.data_ptr = NULL;
|
||||
event.event_type = cur->timer_event_type;
|
||||
event.event_id = cur->timer_sys_launch_message;
|
||||
event.event_data = 0;
|
||||
event.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();
|
||||
}
|
||||
|
Loading…
Reference in New Issue