feat(UML-1462): Добавлен пример пользовательского функтора и комментарии
This commit is contained in:
parent
64e4f695f8
commit
d9fb921cd4
@ -9,6 +9,17 @@
|
||||
|
||||
namespace free_rtos {
|
||||
|
||||
/*
|
||||
* Порядок инициализации:
|
||||
* Инициализировать и открыть драйвер eth_.Init(...), eth_.Open()
|
||||
* Вызвать EthEcatApi::init(eth_);
|
||||
* Создать служебный поток ecat_task_.Create(...) с вызовом EthEcatApi::process()
|
||||
* Вызвать EthEcatApi::config_init(...)
|
||||
* Создать пользовательский поток ecat_task_pdo_.Create(...)
|
||||
* Для чтения/записи данных в пользовательском потоке вызвать
|
||||
* pdo_write(...), pdo_read(...) или pdo_write_async(...), pdo_read_async(...)
|
||||
*/
|
||||
|
||||
Eth *EthEcatApi::eth_{nullptr};
|
||||
|
||||
void EthEcatApi::init(Eth& eth) {
|
||||
|
@ -23,7 +23,11 @@ void EthEcatBuffer::init(uint16_t rx_eeprom_addr, uint16_t tx_eeprom_addr) {
|
||||
for(EcatSlave& slave : slaves) {
|
||||
buffer_slaves_.emplace_back(EcatBufferSlave{slave});
|
||||
}
|
||||
|
||||
/*
|
||||
for(EcatBufferSlave& buffer_slave : buffer_slaves_) {
|
||||
buffer_slave.read_info_from_eeprom<command::FP>(eeprom);
|
||||
}
|
||||
*/
|
||||
for(EcatBufferSlave& buffer_slave : buffer_slaves_) {
|
||||
buffer_slave.read_buffer_info_from_eeprom<command::FP>(eeprom, rx_eeprom_addr, tx_eeprom_addr);
|
||||
}
|
||||
|
@ -17,8 +17,8 @@
|
||||
namespace free_rtos {
|
||||
|
||||
enum {
|
||||
ECT_PDOOUTPUTOFFSET = 0x1100, // write, output, rx buffer offset
|
||||
ECT_PDOINPUTOFFSET = 0x1400 // read, input, tx buffer offset
|
||||
ECT_PDOOUTPUTOFFSET = 0x1100, // 0x1100 write, output, rx buffer offset
|
||||
ECT_PDOINPUTOFFSET = 0x1400 // 0x1400, 0x1140 read, input, tx buffer offset
|
||||
};
|
||||
|
||||
enum {
|
||||
@ -153,6 +153,20 @@ public:
|
||||
return fmmu_properties_read_;
|
||||
}
|
||||
|
||||
template<typename TypeT>
|
||||
void read_info_from_eeprom(eeprom::EEPROM& eeprom) {
|
||||
auto slave_address = slave_.get_slave_address<TypeT>();
|
||||
uint32_t word{0x00000000};
|
||||
|
||||
for(uint16_t addr = 0x0000; addr < 128; addr += 2) {
|
||||
eeprom.read<TypeT>(slave_address, addr, word);
|
||||
|
||||
DebugP_log((char*)"0x%04x \r\n", word);
|
||||
}
|
||||
|
||||
DebugP_log((char*)"\r\n");
|
||||
}
|
||||
|
||||
template<typename TypeT>
|
||||
void read_buffer_info_from_eeprom(eeprom::EEPROM& eeprom, uint16_t rx_eeprom_addr, uint16_t tx_eeprom_addr) {
|
||||
auto slave_address = slave_.get_slave_address<TypeT>();
|
||||
|
@ -189,6 +189,56 @@ private:
|
||||
Future<DataTypes...> future_;
|
||||
};
|
||||
|
||||
/*
|
||||
Объект FunctorT реализует пользователь под собственные нужды и должен иметь вид
|
||||
|
||||
class UserFunctor {
|
||||
public:
|
||||
// В конструктор можно передать переменные из пользовательского контекста
|
||||
UserFunctor(address::Offset offset, std::vector<uint8_t>& data)
|
||||
: offset_{offset}
|
||||
, data_{data} { }
|
||||
|
||||
bool get_ready() {
|
||||
return ready_;
|
||||
}
|
||||
|
||||
void operator()(uint8_t* process_data, uint32_t len) {
|
||||
// Обработка коллбека пользователем
|
||||
size_t size = data_.size() * sizeof(uint8_t);
|
||||
|
||||
memcpy(data_.data(), process_data + offset_, size);
|
||||
|
||||
ready_ = true;
|
||||
|
||||
// DebugP_log((char*)"Запрос обработан !\r\n");
|
||||
}
|
||||
|
||||
private:
|
||||
// Переменные из пользовательского контекста
|
||||
address::Offset offset_{0};
|
||||
std::vector<uint8_t>& data_;
|
||||
|
||||
bool ready_{false};
|
||||
};
|
||||
|
||||
*/
|
||||
|
||||
template<typename FunctorT>
|
||||
class FunctorPromise : public IPromise {
|
||||
public:
|
||||
FunctorPromise(FunctorT& functor)
|
||||
: IPromise{0}
|
||||
, functor_(functor) { }
|
||||
|
||||
virtual void set_value(uint8_t* process_data, uint32_t len) override {
|
||||
functor_(process_data, len);
|
||||
}
|
||||
|
||||
private:
|
||||
FunctorT& functor_;
|
||||
};
|
||||
|
||||
} // namespace custom_promise
|
||||
|
||||
} // namespace free_rtos
|
||||
|
@ -68,8 +68,17 @@ uint8_t* EcatTelegram::unpack(uint8_t *raw) {
|
||||
uint8_t *p_datagram_last = p_datagram_first;
|
||||
datagram::IEcatDatagram *next = datagram_queue_;
|
||||
|
||||
(void)p_eth_hdr;
|
||||
(void)p_hdr;
|
||||
if(p_eth_hdr->prot_id != ETH_PROT_ECAT_LE) {
|
||||
DebugP_log((char*)"Error: wrong protocol ID\r\n");
|
||||
|
||||
return raw;
|
||||
}
|
||||
|
||||
if(p_hdr->bits.type != static_cast<uint16_t>(ec_network::PROTOCOL_TYPE)) {
|
||||
DebugP_log((char*)"Error: wrong ethercat protocol type\r\n");
|
||||
|
||||
return raw;
|
||||
}
|
||||
|
||||
while(next != nullptr) {
|
||||
p_datagram_last = next->unpack(p_datagram_last);
|
||||
@ -82,9 +91,6 @@ uint8_t* EcatTelegram::unpack(uint8_t *raw) {
|
||||
void EcatTelegram::transfer(datagram::IEcatDatagram& first) {
|
||||
datagram_queue_ = &first;
|
||||
|
||||
//uint8_t *raw = pack(buffer_out_.data);
|
||||
//bool stat = tx_flow_.send(port_id_, buffer_out_.data, raw - buffer_out_.data);
|
||||
|
||||
bool stat = eth_stack_.send_pkt(port_id_, ETH_PROT_ECAT_LE, 1);
|
||||
|
||||
if(stat == false) {
|
||||
|
@ -20,7 +20,6 @@ class EcatTelegram : public Handler {
|
||||
public:
|
||||
EcatTelegram(Eth& eth)
|
||||
: eth_{eth}
|
||||
, tx_flow_{*eth.getTxFlowPtr()}
|
||||
, eth_stack_{*eth.getEthStackPtr()} { }
|
||||
|
||||
virtual int32_t Process(uint8_t *p_data, uint32_t len) override;
|
||||
@ -35,7 +34,6 @@ public:
|
||||
|
||||
private:
|
||||
Eth& eth_;
|
||||
EthTxFlowIface& tx_flow_;
|
||||
EthStackIface& eth_stack_;
|
||||
TEthMacPorts port_id_;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user