fix(SF-60): Исправлен баг семафора и включено профилирование приема ethercat
This commit is contained in:
parent
7822f5e3d7
commit
f0cbde9013
@ -96,8 +96,12 @@ uint8_t* EcatTelegram::unpack(uint8_t *raw) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool EcatTelegram::transfer() {
|
bool EcatTelegram::transfer() {
|
||||||
|
MAKE_AUTO_PROFILER(transfer, 32);
|
||||||
|
|
||||||
auto first = datagram_queue_.get_first();
|
auto first = datagram_queue_.get_first();
|
||||||
uint32_t transfer_attempts = 0;
|
uint32_t transfer_attempts = 0;
|
||||||
|
uint32_t tick_counter_start;
|
||||||
|
uint32_t tick_counter_diff;
|
||||||
bool status = (first == nullptr);
|
bool status = (first == nullptr);
|
||||||
int32_t sts;
|
int32_t sts;
|
||||||
|
|
||||||
@ -112,7 +116,7 @@ bool EcatTelegram::transfer() {
|
|||||||
first->reset_all_wkc();
|
first->reset_all_wkc();
|
||||||
|
|
||||||
while(1) {
|
while(1) {
|
||||||
ecat_timer_.Wait();
|
tick_counter_start = ecat_timer_.Wait();
|
||||||
|
|
||||||
transfer_attempts++;
|
transfer_attempts++;
|
||||||
status = (transfer_attempts <= max_transfer_attempts_);
|
status = (transfer_attempts <= max_transfer_attempts_);
|
||||||
@ -124,12 +128,13 @@ bool EcatTelegram::transfer() {
|
|||||||
status_.result = EcatTelegramResult::FATAL_ERROR;
|
status_.result = EcatTelegramResult::FATAL_ERROR;
|
||||||
|
|
||||||
DebugP_log((char*)"%s: %d\r\n", status_.get_description().string, max_transfer_attempts_);
|
DebugP_log((char*)"%s: %d\r\n", status_.get_description().string, max_transfer_attempts_);
|
||||||
|
DebugP_log((char*)"Tick counter diff: %d/%d\r\n", tick_counter_diff, counter_timeout_ticks_);
|
||||||
|
DebugP_log((char*)"Last profiler item %lld cycles\r\n", GET_LAST_PROFILER_ITEM(transfer));
|
||||||
|
FORCE_DUMP_PROFILER(transfer);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
//START_PROFILER_STATIC_ITEM(Test_static, 128, 0);
|
|
||||||
|
|
||||||
// status = eth_stack_.send_pkt(port_id_, ETH_PROT_ECAT_LE, 1);
|
// status = eth_stack_.send_pkt(port_id_, ETH_PROT_ECAT_LE, 1);
|
||||||
status = tx_flow_.send(port_id_, this, 1);
|
status = tx_flow_.send(port_id_, this, 1);
|
||||||
|
|
||||||
@ -142,13 +147,25 @@ bool EcatTelegram::transfer() {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
do {
|
{
|
||||||
sts = rx_sem_.pend(connection_timeout_ticks_);
|
MAKE_PROFILER_AUTO_ITEM(transfer, 32, 0);
|
||||||
} while(sts == SystemP_FAILURE);
|
|
||||||
|
|
||||||
//STOP_PROFILER_STATIC_ITEM(Test_static, 128, 0);
|
do {
|
||||||
|
sts = rx_sem_.pend(semaphore_timeout_ticks_);
|
||||||
|
|
||||||
if(sts == SystemP_TIMEOUT) {
|
tick_counter_diff = diff(tick_counter_start, ecat_timer_.GetTickCounter());
|
||||||
|
|
||||||
|
if((sts != SystemP_SUCCESS) && (tick_counter_diff < counter_timeout_ticks_)) {
|
||||||
|
//DebugP_log((char*)"rx_sem_ fake timeout detected !\r\n", );
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
} while(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(sts != SystemP_SUCCESS) {
|
||||||
status_.transfer_errors++;
|
status_.transfer_errors++;
|
||||||
status_.result = EcatTelegramResult::WARNING_TIMEOUT_ERROR;
|
status_.result = EcatTelegramResult::WARNING_TIMEOUT_ERROR;
|
||||||
|
|
||||||
|
|||||||
@ -73,11 +73,24 @@ public:
|
|||||||
eth_.getEthStackPtr()->Register(ETH_PROT_ECAT_LE, this);
|
eth_.getEthStackPtr()->Register(ETH_PROT_ECAT_LE, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static uint32_t diff(uint32_t tick_counter_start, uint32_t tick_counter_current) {
|
||||||
|
uint32_t tick_counter_diff;
|
||||||
|
|
||||||
|
if(tick_counter_current >= tick_counter_start) {
|
||||||
|
tick_counter_diff = tick_counter_current - tick_counter_start;
|
||||||
|
}else{
|
||||||
|
tick_counter_diff = tick_counter_current + (0xFFFFFFFF - tick_counter_start);
|
||||||
|
}
|
||||||
|
|
||||||
|
return tick_counter_diff;
|
||||||
|
}
|
||||||
|
|
||||||
bool transfer(datagram::IEcatDatagram& next);
|
bool transfer(datagram::IEcatDatagram& next);
|
||||||
bool transfer(queue::Queue<datagram::IEcatDatagram>& next);
|
bool transfer(queue::Queue<datagram::IEcatDatagram>& next);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static constexpr uint32_t connection_timeout_ticks_ = 70;
|
static constexpr uint32_t semaphore_timeout_ticks_ = 2;
|
||||||
|
static constexpr uint32_t counter_timeout_ticks_ = 8;
|
||||||
static constexpr uint32_t max_transfer_attempts_ = 6;
|
static constexpr uint32_t max_transfer_attempts_ = 6;
|
||||||
|
|
||||||
Eth& eth_;
|
Eth& eth_;
|
||||||
|
|||||||
@ -56,8 +56,9 @@ class QuickProfilerStaticItem;
|
|||||||
template<size_t size>
|
template<size_t size>
|
||||||
class QuickProfiler {
|
class QuickProfiler {
|
||||||
public:
|
public:
|
||||||
QuickProfiler(const char *name)
|
QuickProfiler(const char *name, bool auto_dump = false)
|
||||||
: name_{name} { };
|
: name_{name}
|
||||||
|
, auto_dump_{auto_dump} { };
|
||||||
|
|
||||||
QuickProfilerAutoItem<size> makeProfilerAutoItem() {
|
QuickProfilerAutoItem<size> makeProfilerAutoItem() {
|
||||||
return QuickProfilerAutoItem<size>{*this};
|
return QuickProfilerAutoItem<size>{*this};
|
||||||
@ -67,7 +68,7 @@ public:
|
|||||||
return QuickProfilerStaticItem<size>{*this};
|
return QuickProfilerStaticItem<size>{*this};
|
||||||
}
|
}
|
||||||
|
|
||||||
void collect(uint64_t diff, bool toDump) {
|
void collect(uint64_t diff) {
|
||||||
uint32_t counter = counter_;
|
uint32_t counter = counter_;
|
||||||
buffer_[counter] = diff;
|
buffer_[counter] = diff;
|
||||||
|
|
||||||
@ -76,7 +77,7 @@ public:
|
|||||||
if(counter >= size) {
|
if(counter >= size) {
|
||||||
counter = 0;
|
counter = 0;
|
||||||
|
|
||||||
if(toDump == true) {
|
if(auto_dump_ == true) {
|
||||||
dump();
|
dump();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -111,7 +112,7 @@ public:
|
|||||||
uint32_t min{0xFFFFFFFF};
|
uint32_t min{0xFFFFFFFF};
|
||||||
uint32_t max{0x00000000};
|
uint32_t max{0x00000000};
|
||||||
|
|
||||||
for(uint32_t value : buffer_) {
|
for(uint64_t value : buffer_) {
|
||||||
average += value/size;
|
average += value/size;
|
||||||
|
|
||||||
if(value < min) {
|
if(value < min) {
|
||||||
@ -126,12 +127,12 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
DebugP_log((char *)"\r\n");
|
DebugP_log((char *)"\r\n");
|
||||||
|
|
||||||
DebugP_log((char *)"Profiler %s average: %lld min: %d max: %d\r\n", name_, average, min, max);
|
DebugP_log((char *)"Profiler %s average: %lld min: %d max: %d\r\n", name_, average, min, max);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const char *name_;
|
const char *name_;
|
||||||
|
const bool auto_dump_{false};
|
||||||
size_t counter_{0};
|
size_t counter_{0};
|
||||||
std::array<uint64_t, size> buffer_;
|
std::array<uint64_t, size> buffer_;
|
||||||
|
|
||||||
@ -140,7 +141,7 @@ private:
|
|||||||
uint32_t min{0xFFFFFFFF};
|
uint32_t min{0xFFFFFFFF};
|
||||||
uint32_t max{0x00000000};
|
uint32_t max{0x00000000};
|
||||||
|
|
||||||
for(uint32_t value : buffer_) {
|
for(uint64_t value : buffer_) {
|
||||||
average += value/size;
|
average += value/size;
|
||||||
|
|
||||||
if(value < min) {
|
if(value < min) {
|
||||||
@ -152,9 +153,7 @@ private:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(average > 60000) {
|
DebugP_log((char *)"Profiler %s average: %lld min: %d max: %d\r\n", name_, average, min, max);
|
||||||
DebugP_log((char *)"Profiler %s average: %lld min: %d max: %d\r\n", name_, average, min, max);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -177,7 +176,7 @@ public:
|
|||||||
diff = (0xFFFFFFFFU - start_cycle) + end_cycle;
|
diff = (0xFFFFFFFFU - start_cycle) + end_cycle;
|
||||||
}
|
}
|
||||||
|
|
||||||
profiler_.collect(diff, true);
|
profiler_.collect(diff);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -206,7 +205,7 @@ public:
|
|||||||
diff = (0xFFFFFFFFU - start_cycle) + end_cycle;
|
diff = (0xFFFFFFFFU - start_cycle) + end_cycle;
|
||||||
}
|
}
|
||||||
|
|
||||||
profiler_.collect(diff, true);
|
profiler_.collect(diff);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@ -17,6 +17,7 @@ void free_rtos::timer_isr_callback(void * arg)
|
|||||||
Timer * const p_timer = (Timer * const)arg;
|
Timer * const p_timer = (Timer * const)arg;
|
||||||
|
|
||||||
p_timer->sem_.post();
|
p_timer->sem_.post();
|
||||||
|
++p_timer->tick_counter_;
|
||||||
|
|
||||||
TimerP_clearOverflowInt(p_timer->base_addr_);
|
TimerP_clearOverflowInt(p_timer->base_addr_);
|
||||||
HwiP_clearInt(p_timer->int_num_);
|
HwiP_clearInt(p_timer->int_num_);
|
||||||
@ -60,8 +61,10 @@ bool free_rtos::Timer::Init(Settings& sett)
|
|||||||
return (status == SystemP_SUCCESS);
|
return (status == SystemP_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
void free_rtos::Timer::Wait() {
|
uint32_t free_rtos::Timer::Wait() {
|
||||||
sem_.pend();
|
sem_.pend();
|
||||||
|
|
||||||
|
return tick_counter_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void free_rtos::Timer::Start() {
|
void free_rtos::Timer::Start() {
|
||||||
|
|||||||
@ -35,11 +35,15 @@ public:
|
|||||||
/**
|
/**
|
||||||
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>. <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
|
* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>. <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
|
||||||
*/
|
*/
|
||||||
void Wait();
|
uint32_t Wait();
|
||||||
|
|
||||||
void Start();
|
void Start();
|
||||||
|
|
||||||
void Stop();
|
void Stop();
|
||||||
|
|
||||||
|
uint32_t GetTickCounter() {
|
||||||
|
return tick_counter_;
|
||||||
|
}
|
||||||
private:
|
private:
|
||||||
friend void timer_isr_callback(void * arg);
|
friend void timer_isr_callback(void * arg);
|
||||||
|
|
||||||
@ -49,6 +53,7 @@ private:
|
|||||||
HwiP_Object hwi_obj_; /// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
HwiP_Object hwi_obj_; /// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||||||
|
|
||||||
Semaphore sem_;
|
Semaphore sem_;
|
||||||
|
uint32_t tick_counter_{0x00000000};
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user