From 58bf40b55d46674c7fc833cdfd199ff165817484 Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Fri, 27 Oct 2017 09:51:57 +0100 Subject: [PATCH 1/5] Amalgamated ecl_timer_list into ecl_timer --- .../ArmTimerCallbacks.uvoptx | 26 +-- .../ArmTimerCallbacks.uvprojx | 16 +- src/c/ecl_timer.c | 169 ++++++++++++++- src/c/ecl_timer_list.c | 201 ------------------ src/c/ecl_timer_list.h | 44 ---- 5 files changed, 172 insertions(+), 284 deletions(-) delete mode 100644 src/c/ecl_timer_list.c delete mode 100644 src/c/ecl_timer_list.h diff --git a/examples/ArmTimerCallbacks - C/ArmTimerCallbacks.uvoptx b/examples/ArmTimerCallbacks - C/ArmTimerCallbacks.uvoptx index a96071c6..f18af392 100644 --- a/examples/ArmTimerCallbacks - C/ArmTimerCallbacks.uvoptx +++ b/examples/ArmTimerCallbacks - C/ArmTimerCallbacks.uvoptx @@ -248,18 +248,6 @@ 1 3 - 1 - 0 - 0 - 0 - ..\..\src\c\ecl_timer_list.c - ecl_timer_list.c - 0 - 0 - - - 1 - 4 5 0 0 @@ -271,19 +259,7 @@ 1 - 5 - 5 - 0 - 0 - 0 - ..\..\src\c\ecl_timer_list.h - ecl_timer_list.h - 0 - 0 - - - 1 - 6 + 4 5 0 0 diff --git a/examples/ArmTimerCallbacks - C/ArmTimerCallbacks.uvprojx b/examples/ArmTimerCallbacks - C/ArmTimerCallbacks.uvprojx index 28b06f23..1dab4f9a 100644 --- a/examples/ArmTimerCallbacks - C/ArmTimerCallbacks.uvprojx +++ b/examples/ArmTimerCallbacks - C/ArmTimerCallbacks.uvprojx @@ -10,8 +10,8 @@ Target 1 0x4 ARM-ADS - 5060528::V5.06 update 5 (build 528)::ARMCC - 0 + 6070000::V6.7::.\ARMCLANG + 1 STM32F401RETx @@ -320,7 +320,7 @@ 1 0 0 - 2 + 3 0 0 1 @@ -390,21 +390,11 @@ 1 ..\..\src\c\ecl_timer.c - - ecl_timer_list.c - 1 - ..\..\src\c\ecl_timer_list.c - ecl_timer.h 5 ..\..\src\c\ecl_timer.h - - ecl_timer_list.h - 5 - ..\..\src\c\ecl_timer_list.h - ecl_user.h 5 diff --git a/src/c/ecl_timer.c b/src/c/ecl_timer.c index 29b5b17b..2b6e3e77 100644 --- a/src/c/ecl_timer.c +++ b/src/c/ecl_timer.c @@ -30,7 +30,174 @@ SOFTWARE. #include #include "ecl_timer.h" -#include "ecl_timer_list.h" + +//***************************************************************************** +// Internal timer list +//***************************************************************************** + +static ecl_timer_id_t head; +static ecl_timer_id_t tail; +static ecl_timer_id_t current; + +static struct ecl_timer_config* ptimers; + +static void ecl_timer_list_init(struct ecl_timer_config* const ptimers_) +{ + ptimers = ptimers_; + head = ECL_TIMER_NO_TIMER; + tail = ECL_TIMER_NO_TIMER; + current = ECL_TIMER_NO_TIMER; +} + +//******************************* +static struct ecl_timer_config* ecl_timer_list_front() +{ + return &ptimers[head]; +} + +//******************************* +static ecl_timer_id_t ecl_timer_list_begin() +{ + current = head; + return current; +} + +//******************************* +static ecl_timer_id_t ecl_timer_list_next(ecl_timer_id_t last) +{ + current = ptimers[last].next; + return current; +} + +//******************************* +static int ecl_timer_list_empty() +{ + return head == ECL_TIMER_NO_TIMER; +} + +//******************************* +// Inserts the timer at the correct delta position +//******************************* +static void ecl_timer_list_insert(ecl_timer_id_t id_) +{ + struct ecl_timer_config* ptimer = &ptimers[id_]; + + if (head == ECL_TIMER_NO_TIMER) + { + // No entries yet. + head = id_; + tail = id_; + ptimer->previous = ECL_TIMER_NO_TIMER; + ptimer->next = ECL_TIMER_NO_TIMER; + } + else + { + // We already have entries. + ecl_timer_id_t test_id = ecl_timer_list_begin(); + + while (test_id != ECL_TIMER_NO_TIMER) + { + struct ecl_timer_config* ptest = &ptimers[test_id]; + + // Find the correct place to insert. + if (ptimer->delta <= ptest->delta) + { + if (ptest->id == head) + { + head = ptimer->id; + } + + // Insert before ptest-> + ptimer->previous = ptest->previous; + ptest->previous = ptimer->id; + ptimer->next = ptest->id; + + // Adjust the next delta to compensate. + ptest->delta -= ptimer->delta; + + if (ptimer->previous != ECL_TIMER_NO_TIMER) + { + ptimers[ptimer->previous].next = ptimer->id; + } + break; + } + else + { + ptimer->delta -= ptest->delta; + } + + test_id = ecl_timer_list_next(test_id); + } + + // Reached the end? + if (test_id == ECL_TIMER_NO_TIMER) + { + // Tag on to the tail. + ptimers[tail].next = ptimer->id; + ptimer->previous = tail; + ptimer->next = ECL_TIMER_NO_TIMER; + tail = ptimer->id; + } + } +} + +//******************************* +static void ecl_timer_list_remove(ecl_timer_id_t id_, int has_expired) +{ + struct ecl_timer_config* ptimer = &ptimers[id_]; + + if (head == id_) + { + head = ptimer->next; + } + else + { + ptimers[ptimer->previous].next = ptimer->next; + } + + if (tail == id_) + { + tail = ptimer->previous; + } + else + { + ptimers[ptimer->next].previous = ptimer->previous; + } + + if (!has_expired) + { + // Adjust the next delta. + if (ptimer->next != ECL_TIMER_NO_TIMER) + { + ptimers[ptimer->next].delta += ptimer->delta; + } + } + + ptimer->previous = ECL_TIMER_NO_TIMER; + ptimer->next = ECL_TIMER_NO_TIMER; + ptimer->delta = ECL_TIMER_INACTIVE; +} + +//******************************* +static void ecl_timer_list_clear() +{ + ecl_timer_id_t id = ecl_timer_list_begin(); + + while (id != ECL_TIMER_NO_TIMER) + { + struct ecl_timer_config* ptimer = &ptimers[id]; + id = ecl_timer_list_next(id); + ptimer->next = ECL_TIMER_NO_TIMER; + } + + head = ECL_TIMER_NO_TIMER; + tail = ECL_TIMER_NO_TIMER; + current = ECL_TIMER_NO_TIMER; +} + +//***************************************************************************** +// Timer Framework +//***************************************************************************** //******************************************* /// Default initialisation. diff --git a/src/c/ecl_timer_list.c b/src/c/ecl_timer_list.c deleted file mode 100644 index 1e728ff0..00000000 --- a/src/c/ecl_timer_list.c +++ /dev/null @@ -1,201 +0,0 @@ -/****************************************************************************** -The MIT License(MIT) - -Embedded Template Library. -https://github.com/ETLCPP/etl -https://www.etlcpp.com - -Copyright(c) 2017 jwellbelove - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files(the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and / or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions : - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -******************************************************************************/ - -#include "ecl_timer.h" -#include "ecl_timer_list.h" - -//************************************************************************* -/// A specialised intrusive linked list for timer data. -//************************************************************************* - -static ecl_timer_id_t head; -static ecl_timer_id_t tail; -static ecl_timer_id_t current; - -struct ecl_timer_config* ptimers; - -void ecl_timer_list_init(struct ecl_timer_config* const ptimers_) -{ - ptimers = ptimers_; - head = ECL_TIMER_NO_TIMER; - tail = ECL_TIMER_NO_TIMER; - current = ECL_TIMER_NO_TIMER; -} - -//******************************* -struct ecl_timer_config* ecl_timer_list_front() -{ - return &ptimers[head]; -} - -//******************************* -ecl_timer_id_t ecl_timer_list_begin() -{ - current = head; - return current; -} - -//******************************* -ecl_timer_id_t ecl_timer_list_previous(ecl_timer_id_t last) -{ - current = ptimers[last].previous; - return current; -} - -//******************************* -ecl_timer_id_t ecl_timer_list_next(ecl_timer_id_t last) -{ - current = ptimers[last].next; - return current; -} - -//******************************* -int ecl_timer_list_empty() -{ - return head == ECL_TIMER_NO_TIMER; -} - -//******************************* -// Inserts the timer at the correct delta position -//******************************* -void ecl_timer_list_insert(ecl_timer_id_t id_) -{ - struct ecl_timer_config* ptimer = &ptimers[id_]; - - if (head == ECL_TIMER_NO_TIMER) - { - // No entries yet. - head = id_; - tail = id_; - ptimer->previous = ECL_TIMER_NO_TIMER; - ptimer->next = ECL_TIMER_NO_TIMER; - } - else - { - // We already have entries. - ecl_timer_id_t test_id = ecl_timer_list_begin(); - - while (test_id != ECL_TIMER_NO_TIMER) - { - struct ecl_timer_config* ptest = &ptimers[test_id]; - - // Find the correct place to insert. - if (ptimer->delta <= ptest->delta) - { - if (ptest->id == head) - { - head = ptimer->id; - } - - // Insert before ptest-> - ptimer->previous = ptest->previous; - ptest->previous = ptimer->id; - ptimer->next = ptest->id; - - // Adjust the next delta to compensate. - ptest->delta -= ptimer->delta; - - if (ptimer->previous != ECL_TIMER_NO_TIMER) - { - ptimers[ptimer->previous].next = ptimer->id; - } - break; - } - else - { - ptimer->delta -= ptest->delta; - } - - test_id = ecl_timer_list_next(test_id); - } - - // Reached the end? - if (test_id == ECL_TIMER_NO_TIMER) - { - // Tag on to the tail. - ptimers[tail].next = ptimer->id; - ptimer->previous = tail; - ptimer->next = ECL_TIMER_NO_TIMER; - tail = ptimer->id; - } - } -} - -//******************************* -void ecl_timer_list_remove(ecl_timer_id_t id_, int has_expired) -{ - struct ecl_timer_config* ptimer = &ptimers[id_]; - - if (head == id_) - { - head = ptimer->next; - } - else - { - ptimers[ptimer->previous].next = ptimer->next; - } - - if (tail == id_) - { - tail = ptimer->previous; - } - else - { - ptimers[ptimer->next].previous = ptimer->previous; - } - - if (!has_expired) - { - // Adjust the next delta. - if (ptimer->next != ECL_TIMER_NO_TIMER) - { - ptimers[ptimer->next].delta += ptimer->delta; - } - } - - ptimer->previous = ECL_TIMER_NO_TIMER; - ptimer->next = ECL_TIMER_NO_TIMER; - ptimer->delta = ECL_TIMER_INACTIVE; -} - -//******************************* -void ecl_timer_list_clear() -{ - ecl_timer_id_t id = ecl_timer_list_begin(); - - while (id != ECL_TIMER_NO_TIMER) - { - struct ecl_timer_config* ptimer = &ptimers[id]; - id = ecl_timer_list_next(id); - ptimer->next = ECL_TIMER_NO_TIMER; - } - - head = ECL_TIMER_NO_TIMER; - tail = ECL_TIMER_NO_TIMER; - current = ECL_TIMER_NO_TIMER; -} diff --git a/src/c/ecl_timer_list.h b/src/c/ecl_timer_list.h deleted file mode 100644 index 7662b48e..00000000 --- a/src/c/ecl_timer_list.h +++ /dev/null @@ -1,44 +0,0 @@ -/****************************************************************************** -The MIT License(MIT) - -Embedded Template Library. -https://github.com/ETLCPP/etl -https://www.etlcpp.com - -Copyright(c) 2017 jwellbelove - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files(the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and / or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions : - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -******************************************************************************/ - -#ifndef __ETL_C_TIMER_FRAMEWORK_LIST__ -#define __ETL_C_TIMER_FRAMEWORK_LIST__ - -#include "ecl_timer.h" - -void ecl_timer_list_init(struct ecl_timer_config* const ptimers_); -struct ecl_timer_config* ecl_timer_list_front(void); -ecl_timer_id_t ecl_timer_list_begin(void); -ecl_timer_id_t ecl_timer_list_previous(ecl_timer_id_t last); -ecl_timer_id_t ecl_timer_list_next(ecl_timer_id_t last); -int ecl_timer_list_empty(void); -void ecl_timer_list_insert(ecl_timer_id_t id_); -void ecl_timer_list_remove(ecl_timer_id_t id_, int has_expired); -void ecl_timer_list_clear(void); - -#endif From a6f3bcd17ea47d2de3c9fdad76165ed35edea06e Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Fri, 27 Oct 2017 10:03:25 +0100 Subject: [PATCH 2/5] Fixed issue where on_exit_state was being called after the state had changed. --- src/fsm_generator.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fsm_generator.h b/src/fsm_generator.h index fc18c240..d10705f2 100644 --- a/src/fsm_generator.h +++ b/src/fsm_generator.h @@ -318,8 +318,8 @@ namespace etl { do { - p_state = p_next_state; fsm_helper::on_exit_state(*p_state); + p_state = p_next_state; next_state_id = fsm_helper::on_enter_state(*p_state); ETL_ASSERT(next_state_id < number_of_states, ETL_ERROR(etl::fsm_state_id_exception)); From 585a65453ea06aa23b4247426ca88403f2a6457a Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Fri, 27 Oct 2017 10:22:06 +0100 Subject: [PATCH 3/5] Generator was not updated to match the intended generated file. --- src/type_traits_generator.h | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/type_traits_generator.h b/src/type_traits_generator.h index da7d9cf0..0a1471d5 100644 --- a/src/type_traits_generator.h +++ b/src/type_traits_generator.h @@ -428,8 +428,10 @@ namespace etl /// is_base_of ///\ingroup type_traits - template - struct is_base_of + template::value || etl::is_fundamental::value)> + struct is_base_of { private: @@ -444,6 +446,13 @@ namespace etl static const bool value = (sizeof(check((internal*)0)) == sizeof(TBase*)); }; + // For when TBase or TDerived is a fundamental type. + template + struct is_base_of + { + static const bool value = false; + }; + /// Alignment templates. /// These require compiler specific intrinsics. ///\ingroup type_traits From 1c769b0fb2e9157ffda5abb1d3d1ef36b03b768a Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Fri, 27 Oct 2017 11:10:27 +0100 Subject: [PATCH 4/5] Amalgamated ecl_timer_list into ecl_timer --- test/vs2017/etl.vcxproj | 2 -- test/vs2017/etl.vcxproj.filters | 6 ------ 2 files changed, 8 deletions(-) diff --git a/test/vs2017/etl.vcxproj b/test/vs2017/etl.vcxproj index 88a13f2b..d7b2c1dd 100644 --- a/test/vs2017/etl.vcxproj +++ b/test/vs2017/etl.vcxproj @@ -136,7 +136,6 @@ - @@ -300,7 +299,6 @@ - diff --git a/test/vs2017/etl.vcxproj.filters b/test/vs2017/etl.vcxproj.filters index 4c10ab6e..1b3f3f85 100644 --- a/test/vs2017/etl.vcxproj.filters +++ b/test/vs2017/etl.vcxproj.filters @@ -558,9 +558,6 @@ ECL - - ECL - Source Files\ECL @@ -932,9 +929,6 @@ ECL - - ECL - Source Files\ECL From 0c65164483aa6e52f30b91cf84662b2c20e2fecb Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Fri, 27 Oct 2017 11:11:22 +0100 Subject: [PATCH 5/5] Added is_null_router() & is_bus() to imessage_router --- src/message_bus.h | 6 +- src/message_router.h | 12 ++ src/message_router_generator.h | 12 ++ src/message_timer.h | 6 +- test/codeblocks/ETL.cbp | 4 - test/codeblocks/ETL.layout | 294 ++++++++++++++++----------------- 6 files changed, 174 insertions(+), 160 deletions(-) diff --git a/src/message_bus.h b/src/message_bus.h index 00d52a6d..5112629c 100644 --- a/src/message_bus.h +++ b/src/message_bus.h @@ -94,7 +94,7 @@ namespace etl bool ok = true; // There's no point actually adding null routers. - if (router.get_message_router_id() != etl::imessage_router::NULL_MESSAGE_ROUTER) + if (!router.is_null_router()) { ok = !router_list.full(); @@ -102,7 +102,7 @@ namespace etl if (ok) { - if (router.get_message_router_id() == etl::imessage_router::MESSAGE_BUS) + if (router.is_bus()) { // Message busses get added to the end. router_list.push_back(&router); @@ -203,7 +203,7 @@ namespace etl { etl::imessage_router& router = **irouter; - if (router.get_message_router_id() == etl::imessage_router::MESSAGE_BUS) + if (router.is_bus()) { // The router is actually a bus. etl::imessage_bus& bus = static_cast(router); diff --git a/src/message_router.h b/src/message_router.h index 522716b7..091e6560 100644 --- a/src/message_router.h +++ b/src/message_router.h @@ -114,6 +114,18 @@ namespace etl return message_router_id; } + //******************************************** + bool is_null_router() const + { + return (message_router_id == NULL_MESSAGE_ROUTER); + } + + //******************************************** + bool is_bus() const + { + return (message_router_id == MESSAGE_BUS); + } + enum { NULL_MESSAGE_ROUTER = 255, diff --git a/src/message_router_generator.h b/src/message_router_generator.h index 16936bcf..8046b717 100644 --- a/src/message_router_generator.h +++ b/src/message_router_generator.h @@ -126,6 +126,18 @@ namespace etl return message_router_id; } + //******************************************** + bool is_null_router() const + { + return (message_router_id != NULL_MESSAGE_ROUTER); + } + + //******************************************** + bool is_bus() const + { + return (message_router_id != MESSAGE_BUS); + } + enum { NULL_MESSAGE_ROUTER = 255, diff --git a/src/message_timer.h b/src/message_timer.h index b1433d42..f9b863f7 100644 --- a/src/message_timer.h +++ b/src/message_timer.h @@ -81,7 +81,7 @@ namespace etl next(etl::timer::id::NO_TIMER), repeating(repeating_) { - if (irouter_.get_message_router_id() == etl::imessage_router::MESSAGE_BUS) + if (irouter_.is_bus()) { destination_router_id = destination_router_id_; } @@ -330,7 +330,7 @@ namespace etl if (is_space) { // There's no point adding null message routers. - if (router_.get_message_router_id() != etl::imessage_router::NULL_MESSAGE_ROUTER) + if (!router_.is_null_router()) { // Search for the free space. for (uint_least8_t i = 0; i < MAX_TIMERS; ++i) @@ -455,7 +455,7 @@ namespace etl if (timer.p_router != nullptr) { - if (timer.p_router->get_message_router_id() == etl::imessage_router::MESSAGE_BUS) + if (timer.p_router->is_bus()) { // Send to a message bus. etl::imessage_bus& bus = static_cast(*(timer.p_router)); diff --git a/test/codeblocks/ETL.cbp b/test/codeblocks/ETL.cbp index b3b13bf4..ee73a714 100644 --- a/test/codeblocks/ETL.cbp +++ b/test/codeblocks/ETL.cbp @@ -63,10 +63,6 @@