From 6b19bf09e2638e8efd5baeaf95ef1f6f2fd0220a Mon Sep 17 00:00:00 2001 From: Pavel Kirienko Date: Thu, 30 Apr 2015 12:30:13 +0300 Subject: [PATCH] Support for priority in TransferSender --- .../uavcan/transport/transfer_sender.hpp | 25 ++++++++++++++++--- libuavcan/src/transport/uc_frame.cpp | 1 + .../src/transport/uc_transfer_sender.cpp | 15 ++++++++--- 3 files changed, 35 insertions(+), 6 deletions(-) diff --git a/libuavcan/include/uavcan/transport/transfer_sender.hpp b/libuavcan/include/uavcan/transport/transfer_sender.hpp index b67edf23a7..26d6e0e628 100644 --- a/libuavcan/include/uavcan/transport/transfer_sender.hpp +++ b/libuavcan/include/uavcan/transport/transfer_sender.hpp @@ -21,6 +21,7 @@ class UAVCAN_EXPORT TransferSender { const MonotonicDuration max_transfer_interval_; const DataTypeDescriptor& data_type_; + TransferPriority priority_; const CanTxQueue::Qos qos_; const TransferCRC crc_base_; CanIOFlags flags_; @@ -29,7 +30,7 @@ class UAVCAN_EXPORT TransferSender Dispatcher& dispatcher_; - void registerError(); + void registerError() const; public: enum { AllIfacesMask = 0xFF }; @@ -43,6 +44,7 @@ public: MonotonicDuration max_transfer_interval = getDefaultMaxTransferInterval()) : max_transfer_interval_(max_transfer_interval) , data_type_(data_type) + , priority_(TransferPriorityNormal) , qos_(qos) , crc_base_(data_type.getSignature().toTransferCRC()) , flags_(CanIOFlags(0)) @@ -61,6 +63,23 @@ public: iface_mask_ = iface_mask; } + /** + * Transfer priority can be assigned only for message transfers. + * Attempt to change priority of a service transfer will not have any effect. + */ + TransferPriority getPriority() const { return priority_; } + void setPriority(TransferPriority prio) + { + if (prio < NumTransferPriorities && prio != TransferPriorityService) + { + priority_ = prio; + } + else + { + UAVCAN_ASSERT(0); + } + } + /** * Anonymous transfers (i.e. transfers that don't carry a valid Source Node ID) can be sent if * the local node is configured in passive mode (i.e. the node doesn't have a valid Node ID). @@ -76,14 +95,14 @@ public: */ int send(const uint8_t* payload, unsigned payload_len, MonotonicTime tx_deadline, MonotonicTime blocking_deadline, TransferType transfer_type, NodeID dst_node_id, - TransferID tid); + TransferID tid) const; /** * Send with automatic Transfer ID. * TID is managed by OutgoingTransferRegistry. */ int send(const uint8_t* payload, unsigned payload_len, MonotonicTime tx_deadline, - MonotonicTime blocking_deadline, TransferType transfer_type, NodeID dst_node_id); + MonotonicTime blocking_deadline, TransferType transfer_type, NodeID dst_node_id) const; }; } diff --git a/libuavcan/src/transport/uc_frame.cpp b/libuavcan/src/transport/uc_frame.cpp index 045707006d..a732adf84d 100644 --- a/libuavcan/src/transport/uc_frame.cpp +++ b/libuavcan/src/transport/uc_frame.cpp @@ -35,6 +35,7 @@ uint_fast8_t Frame::getMaxIndexForTransferType(const TransferType type) void Frame::setPriority(const TransferPriority priority) { + UAVCAN_ASSERT(priority < NumTransferPriorities); if (transfer_type_ == TransferTypeMessageBroadcast || transfer_type_ == TransferTypeMessageUnicast) { diff --git a/libuavcan/src/transport/uc_transfer_sender.cpp b/libuavcan/src/transport/uc_transfer_sender.cpp index f75b3cc149..6f49f7a635 100644 --- a/libuavcan/src/transport/uc_transfer_sender.cpp +++ b/libuavcan/src/transport/uc_transfer_sender.cpp @@ -10,14 +10,14 @@ namespace uavcan { -void TransferSender::registerError() +void TransferSender::registerError() const { dispatcher_.getTransferPerfCounter().addError(); } int TransferSender::send(const uint8_t* payload, unsigned payload_len, MonotonicTime tx_deadline, MonotonicTime blocking_deadline, TransferType transfer_type, NodeID dst_node_id, - TransferID tid) + TransferID tid) const { if (payload_len > getMaxPayloadLenForTransferType(transfer_type)) { @@ -25,6 +25,12 @@ int TransferSender::send(const uint8_t* payload, unsigned payload_len, Monotonic } Frame frame(data_type_.getID(), transfer_type, dispatcher_.getNodeID(), dst_node_id, 0, tid); + if (transfer_type == TransferTypeMessageBroadcast || + transfer_type == TransferTypeMessageUnicast) + { + UAVCAN_ASSERT(priority_ != TransferPriorityService); + frame.setPriority(priority_); + } UAVCAN_TRACE("TransferSender", "%s", frame.toString().c_str()); /* @@ -126,7 +132,7 @@ int TransferSender::send(const uint8_t* payload, unsigned payload_len, Monotonic } int TransferSender::send(const uint8_t* payload, unsigned payload_len, MonotonicTime tx_deadline, - MonotonicTime blocking_deadline, TransferType transfer_type, NodeID dst_node_id) + MonotonicTime blocking_deadline, TransferType transfer_type, NodeID dst_node_id) const { // This check must be performed before TID is incremented to avoid skipping TID values on failures if (payload_len > getMaxPayloadLenForTransferType(transfer_type)) @@ -134,6 +140,9 @@ int TransferSender::send(const uint8_t* payload, unsigned payload_len, Monotonic return -ErrTransferTooLong; } + /* + * TODO: TID is not needed for anonymous transfers, this part of the code can be skipped? + */ const OutgoingTransferRegistryKey otr_key(data_type_.getID(), transfer_type, dst_node_id); UAVCAN_ASSERT(!tx_deadline.isZero());