diff --git a/components/free_rtos/ethernet/eth_rx_flow.cpp b/components/free_rtos/ethernet/eth_rx_flow.cpp index c936f91..4be4c97 100644 --- a/components/free_rtos/ethernet/eth_rx_flow.cpp +++ b/components/free_rtos/ethernet/eth_rx_flow.cpp @@ -38,6 +38,10 @@ void free_rtos::rxIsrHandler(void *appData) return; } + if(rx_flow->id_ == 1) { + //STOP_PROFILER_STATIC_ITEM(Test_static, 128, 0); + } + //status = EnetDma_retrieveRxPktQ(rx_flow->dma_handle_, &rxReadyQ); //EnetAppUtils_assert(status == ENET_SOK); @@ -232,6 +236,10 @@ void free_rtos::EthRxFlow::rxProcessPktTask() /// ����������� ������� �������� ������� ++rx_pkt_counter_; } + + if(id_ == 1) { + //TRY_DUMP_PROFILER(Test_static); + } } } diff --git a/components/free_rtos/ethernet/eth_rx_flow.hpp b/components/free_rtos/ethernet/eth_rx_flow.hpp index a9a7011..63b7220 100644 --- a/components/free_rtos/ethernet/eth_rx_flow.hpp +++ b/components/free_rtos/ethernet/eth_rx_flow.hpp @@ -16,6 +16,7 @@ #include "free_rtos/handler_store/handler_store.hpp" #include "free_rtos/semaphore/semaphore.hpp" #include "free_rtos/task/task.hpp" +#include "free_rtos/profiler/quick_profiler_static.hpp" #include "free_rtos/ethernet/eth_task_settings.hpp" #include "free_rtos/ethernet/eth_frame.h" diff --git a/components/free_rtos/ethernet/eth_task_settings.hpp b/components/free_rtos/ethernet/eth_task_settings.hpp index 6a9b0b2..9652861 100644 --- a/components/free_rtos/ethernet/eth_task_settings.hpp +++ b/components/free_rtos/ethernet/eth_task_settings.hpp @@ -13,8 +13,8 @@ #include "free_rtos/task/task.hpp" namespace free_rtos { - static constexpr uint32_t LINK_TASK_PRIORITY = tskIDLE_PRIORITY + 2; - static constexpr uint32_t LINK_TASK_STACK_SIZE = (10U * 1024U); + static constexpr uint32_t LINK_TASK_PRIORITY = tskIDLE_PRIORITY + 22; + static constexpr uint32_t LINK_TASK_STACK_SIZE = 0x2000 / sizeof(StackType_t); } #endif /* FREE_RTOS_ETHERNET_ETH_TASK_SETTINGS_HPP_ */ diff --git a/components/free_rtos/ethernet_industry/eth_ecat_api.cpp b/components/free_rtos/ethernet_industry/eth_ecat_api.cpp index 18e74e4..c8e9165 100644 --- a/components/free_rtos/ethernet_industry/eth_ecat_api.cpp +++ b/components/free_rtos/ethernet_industry/eth_ecat_api.cpp @@ -17,7 +17,7 @@ bool EthEcatApi::config_init(TEthMacPorts port_id, uint16_t address_base, uint32 status = ecat_.config_init(address_base); if(status != true) { - DebugP_log((char*)"config_init() failed"); + DebugP_log((char*)"config_init() failed\r\n"); return status; } @@ -25,7 +25,7 @@ bool EthEcatApi::config_init(TEthMacPorts port_id, uint16_t address_base, uint32 status = ecat_buffer_sdo_.init(ECT_SII_RXMBXADR, ECT_SII_TXMBXADR); if(status != true) { - DebugP_log((char*)"ecat_buffer_sdo_.init() failed"); + DebugP_log((char*)"ecat_buffer_sdo_.init() failed\r\n"); return status; } @@ -33,7 +33,7 @@ bool EthEcatApi::config_init(TEthMacPorts port_id, uint16_t address_base, uint32 status = ecat_buffer_sdo_.init_sync_manager(sync_manager::SYNC_M0, sync_manager::SYNC_M1); if(status != true) { - DebugP_log((char*)"ecat_buffer_sdo_.init_sync_manager() failed"); + DebugP_log((char*)"ecat_buffer_sdo_.init_sync_manager() failed\r\n"); return status; } @@ -41,7 +41,7 @@ bool EthEcatApi::config_init(TEthMacPorts port_id, uint16_t address_base, uint32 status = ecat_buffer_pdo_.init(ECT_PDOOUTPUTADR, ECT_PDOINPUTADR); if(status != true) { - DebugP_log((char*)"ecat_buffer_pdo_.init() failed"); + DebugP_log((char*)"ecat_buffer_pdo_.init() failed\r\n"); return status; } @@ -49,7 +49,7 @@ bool EthEcatApi::config_init(TEthMacPorts port_id, uint16_t address_base, uint32 status = ecat_.enable_PDI(); if(status != true) { - DebugP_log((char*)"ecat_.enable_PDI() failed"); + DebugP_log((char*)"ecat_.enable_PDI() failed\r\n"); return status; } @@ -57,7 +57,7 @@ bool EthEcatApi::config_init(TEthMacPorts port_id, uint16_t address_base, uint32 status = ecat_.init_to_preop(); if(status != true) { - DebugP_log((char*)"ecat_.init_to_preop() failed"); + DebugP_log((char*)"ecat_.init_to_preop() failed\r\n"); return status; } @@ -66,7 +66,7 @@ bool EthEcatApi::config_init(TEthMacPorts port_id, uint16_t address_base, uint32 status = ecat_sdo_mailbox_.read_pdo_map(ECT_RXPDOMAPINDEX, ECT_TXPDOMAPINDEX); if(status != true) { - DebugP_log((char*)"ecat_sdo_mailbox_.read_pdo_map() failed"); + DebugP_log((char*)"ecat_sdo_mailbox_.read_pdo_map() failed\r\n"); return status; } @@ -80,7 +80,7 @@ bool EthEcatApi::config_init(TEthMacPorts port_id, uint16_t address_base, uint32 status = ecat_buffer_pdo_.init_sync_manager(sync_manager::SYNC_M2, sync_manager::SYNC_M3); if(status != true) { - DebugP_log((char*)"ecat_buffer_pdo_.init_sync_manager() failed"); + DebugP_log((char*)"ecat_buffer_pdo_.init_sync_manager() failed\r\n"); return status; } @@ -88,7 +88,7 @@ bool EthEcatApi::config_init(TEthMacPorts port_id, uint16_t address_base, uint32 status = ecat_buffer_pdo_.init_fmmu(fmmu::FMMU0, fmmu::FMMU1); if(status != true) { - DebugP_log((char*)"ecat_buffer_pdo_.init_fmmu() failed"); + DebugP_log((char*)"ecat_buffer_pdo_.init_fmmu() failed\r\n"); return status; } @@ -98,7 +98,7 @@ bool EthEcatApi::config_init(TEthMacPorts port_id, uint16_t address_base, uint32 status = ecat_.preop_to_safeop(); if(status != true) { - DebugP_log((char*)"ecat_.preop_to_safeop() failed"); + DebugP_log((char*)"ecat_.preop_to_safeop() failed\r\n"); return status; } @@ -106,7 +106,7 @@ bool EthEcatApi::config_init(TEthMacPorts port_id, uint16_t address_base, uint32 status = ecat_.safeop_to_op(); if(status != true) { - DebugP_log((char*)"ecat_.safeop_to_op() failed"); + DebugP_log((char*)"ecat_.safeop_to_op() failed\r\n"); return status; } diff --git a/components/free_rtos/ethernet_industry/eth_ecat_telegram.cpp b/components/free_rtos/ethernet_industry/eth_ecat_telegram.cpp index f3bc4bc..4185e3a 100644 --- a/components/free_rtos/ethernet_industry/eth_ecat_telegram.cpp +++ b/components/free_rtos/ethernet_industry/eth_ecat_telegram.cpp @@ -99,6 +99,7 @@ bool EcatTelegram::transfer() { auto first = datagram_queue_.get_first(); uint32_t transfer_attempts = 0; bool status = (first == nullptr); + int32_t sts; if(status == true) { status_.result = EcatTelegramResult::SUCCESS; @@ -127,6 +128,8 @@ bool EcatTelegram::transfer() { break; } + //START_PROFILER_STATIC_ITEM(Test_static, 128, 0); + // status = eth_stack_.send_pkt(port_id_, ETH_PROT_ECAT_LE, 1); status = tx_flow_.send(port_id_, this, 1); @@ -139,13 +142,19 @@ bool EcatTelegram::transfer() { continue; } - status = (rx_sem_.pend(connection_timeout_ticks_) == SystemP_SUCCESS); + do { + sts = rx_sem_.pend(connection_timeout_ticks_); + } while(sts == SystemP_FAILURE); - if(status == false) { + //STOP_PROFILER_STATIC_ITEM(Test_static, 128, 0); + + if(sts == SystemP_TIMEOUT) { status_.transfer_errors++; status_.result = EcatTelegramResult::WARNING_TIMEOUT_ERROR; //DebugP_log((char*)"%s: %d\r\n", status_.get_description().string, status_.transfer_errors); + //DebugP_log((char*)"Last profiler item: %lld\r\n", GET_LAST_PROFILER_ITEM(Test_static)); + //FORCE_DUMP_PROFILER(Test_static); continue; } diff --git a/components/free_rtos/ethernet_industry/eth_ecat_telegram.hpp b/components/free_rtos/ethernet_industry/eth_ecat_telegram.hpp index 1d43a9b..160d729 100644 --- a/components/free_rtos/ethernet_industry/eth_ecat_telegram.hpp +++ b/components/free_rtos/ethernet_industry/eth_ecat_telegram.hpp @@ -10,6 +10,7 @@ #include "free_rtos/ethernet/eth.hpp" #include "free_rtos/timer/timer.hpp" +#include "free_rtos/profiler/quick_profiler_static.hpp" #include "free_rtos/ethernet_industry/eth_ecat_datagram.hpp" diff --git a/components/free_rtos/profiler/quick_profiler.cpp b/components/free_rtos/profiler/quick_profiler.cpp new file mode 100644 index 0000000..17724b5 --- /dev/null +++ b/components/free_rtos/profiler/quick_profiler.cpp @@ -0,0 +1,12 @@ +/* + * quick_profiler.cpp + * + * Created on: Oct 4, 2023 + * Author: algin + */ + +#include "quick_profiler.hpp" + +namespace free_rtos { + +} diff --git a/components/free_rtos/profiler/quick_profiler.hpp b/components/free_rtos/profiler/quick_profiler.hpp index 18058cd..d711402 100644 --- a/components/free_rtos/profiler/quick_profiler.hpp +++ b/components/free_rtos/profiler/quick_profiler.hpp @@ -17,12 +17,26 @@ namespace free_rtos { -#define PROFILE(name, size, id) static free_rtos::QuickProfiler name##_profiler{#name}; \ - free_rtos::QuickProfilerItem name##_profile_item_##id{name##_profiler} +#define START_AUTO_PROFILER(name, size, id) static free_rtos::QuickProfiler name##_profiler{#name}; \ + QuickProfilerAutoItem name##_profiler_item_##id = name##_profiler.makeProfilerAutoItem() -#define CREATE_PROFILER(name, size) static free_rtos::QuickProfiler name##_profiler{#name}; +#define MAKE_AUTO_PROFILER(name, size) static free_rtos::QuickProfiler name##_profiler{#name} +#define MAKE_STATIC_PROFILER(name, size) free_rtos::QuickProfiler name##_profiler{#name} -#define ADD_PROFILE_ITEM(name, size, id) free_rtos::QuickProfilerItem name##_profile_item_##id{name##_profiler} +#define FORCE_DUMP_PROFILER(name) name##_profiler.forceDump() + +#define GET_LAST_PROFILER_ITEM(name) name##_profiler.getLast() + +#define EXTERN_PROFILER(name, size) extern QuickProfiler name##_profiler + +#define TRY_DUMP_PROFILER(name) name##_profiler.dumpTry(); + +#define MAKE_PROFILER_AUTO_ITEM(name, size, id) QuickProfilerAutoItem name##_profiler_item_##id = name##_profiler.makeProfilerAutoItem() + +#define MAKE_PROFILER_STATIC_ITEM(name, size, id) QuickProfilerStaticItem name##_profiler_item_##id = name##_profiler.makeProfilerStaticItem() +#define EXTERN_PROFILER_STATIC_ITEM(name, size, id) extern QuickProfilerStaticItem name##_profiler_item_##id +#define START_PROFILER_STATIC_ITEM(name, size, id) name##_profiler_item_##id.start() +#define STOP_PROFILER_STATIC_ITEM(name, size, id) name##_profiler_item_##id.stop() static void QuickProfiler_init(const uint64_t cpuFreqHz) { CycleCounterP_init(cpuFreqHz); @@ -33,13 +47,27 @@ static void QuickProfiler_init(const uint64_t cpuFreqHz) { DebugP_log((char *)"%lld ticks in 1000 nanoseconds\r\n", nsToTicks); } +template +class QuickProfilerAutoItem; + +template +class QuickProfilerStaticItem; + template class QuickProfiler { public: QuickProfiler(const char *name) : name_{name} { }; - void collect(uint32_t diff) { + QuickProfilerAutoItem makeProfilerAutoItem() { + return QuickProfilerAutoItem{*this}; + } + + QuickProfilerStaticItem makeProfilerStaticItem() { + return QuickProfilerStaticItem{*this}; + } + + void collect(uint64_t diff, bool toDump) { uint32_t counter = counter_; buffer_[counter] = diff; @@ -48,16 +76,64 @@ public: if(counter >= size) { counter = 0; + if(toDump == true) { + dump(); + } + } + + counter_ = counter; + } + + void dumpTry() { + uint32_t counter = counter_; + + if(counter == 0) { dump(); } counter_ = counter; } + uint64_t getLast() { + uint32_t counter = counter_; + + if(counter > 0) { + counter = counter - 1; + } else { + counter = size - 1; + } + + return buffer_[counter]; + } + + void forceDump() { + uint64_t average{0x0000000000000000}; + uint32_t min{0xFFFFFFFF}; + uint32_t max{0x00000000}; + + for(uint32_t value : buffer_) { + average += value/size; + + if(value < min) { + min = value; + } + + if(value > max) { + max = value; + } + + DebugP_log((char *)"%lld ", value); + } + + DebugP_log((char *)"\r\n"); + + DebugP_log((char *)"Profiler %s average: %lld min: %d max: %d\r\n", name_, average, min, max); + } + private: const char *name_; size_t counter_{0}; - std::array buffer_; + std::array buffer_; void dump() { uint64_t average{0x0000000000000000}; @@ -65,7 +141,7 @@ private: uint32_t max{0x00000000}; for(uint32_t value : buffer_) { - average += value; + average += value/size; if(value < min) { min = value; @@ -76,24 +152,24 @@ private: } } - average /= size; - - DebugP_log((char *)"Profiler %s average: %lld min: %d max: %d\r\n", name_, average, min, max); + if(average > 60000) { + DebugP_log((char *)"Profiler %s average: %lld min: %d max: %d\r\n", name_, average, min, max); + } } }; template -class QuickProfilerItem { +class QuickProfilerAutoItem { public: - QuickProfilerItem(QuickProfiler& profiler) + QuickProfilerAutoItem(QuickProfiler& profiler) : profiler_{profiler} { start_cycle_ = CycleCounterP_getCount32(); }; - ~QuickProfilerItem() { + ~QuickProfilerAutoItem() { uint32_t end_cycle = CycleCounterP_getCount32(); uint32_t start_cycle = start_cycle_; - uint32_t diff; + uint64_t diff; if(end_cycle > start_cycle) { diff = end_cycle - start_cycle; @@ -101,7 +177,36 @@ public: diff = (0xFFFFFFFFU - start_cycle) + end_cycle; } - profiler_.collect(diff); + profiler_.collect(diff, true); + } + +private: + QuickProfiler& profiler_; + uint32_t start_cycle_; +}; + +template +class QuickProfilerStaticItem { +public: + QuickProfilerStaticItem(QuickProfiler& profiler) + : profiler_{profiler} { }; + + void start() { + start_cycle_ = CycleCounterP_getCount32(); + } + + void stop() { + uint32_t end_cycle = CycleCounterP_getCount32(); + uint32_t start_cycle = start_cycle_; + uint64_t diff; + + if(end_cycle > start_cycle) { + diff = end_cycle - start_cycle; + } else { + diff = (0xFFFFFFFFU - start_cycle) + end_cycle; + } + + profiler_.collect(diff, true); } private: diff --git a/components/free_rtos/profiler/quick_profiler_static.cpp b/components/free_rtos/profiler/quick_profiler_static.cpp new file mode 100644 index 0000000..c6e6613 --- /dev/null +++ b/components/free_rtos/profiler/quick_profiler_static.cpp @@ -0,0 +1,15 @@ +/* + * quick_profiler_static.cpp + * + * Created on: Oct 4, 2023 + * Author: algin + */ + +#include "quick_profiler_static.hpp" + +namespace free_rtos { + +MAKE_STATIC_PROFILER(Test_static, 128); +MAKE_PROFILER_STATIC_ITEM(Test_static, 128, 0); + +} diff --git a/components/free_rtos/profiler/quick_profiler_static.hpp b/components/free_rtos/profiler/quick_profiler_static.hpp new file mode 100644 index 0000000..d0b45c0 --- /dev/null +++ b/components/free_rtos/profiler/quick_profiler_static.hpp @@ -0,0 +1,20 @@ +/* + * quick_profiler_static.hpp + * + * Created on: Oct 4, 2023 + * Author: algin + */ + +#ifndef FREE_RTOS_PROFILER_QUICK_PROFILER_STATIC_HPP_ +#define FREE_RTOS_PROFILER_QUICK_PROFILER_STATIC_HPP_ + +#include "quick_profiler.hpp" + +namespace free_rtos { + +EXTERN_PROFILER(Test_static, 128); +EXTERN_PROFILER_STATIC_ITEM(Test_static, 128, 0); + +} + +#endif /* FREE_RTOS_PROFILER_QUICK_PROFILER_STATIC_HPP_ */