From 6672185fbc40956e8e5e9e044da9294c9f04dbb5 Mon Sep 17 00:00:00 2001 From: Ashish Chaudhari Date: Tue, 8 Apr 2014 10:31:57 -0700 Subject: nirio: Added fifo channel to start and stop RIO syncop params. --- host/include/uhd/transport/nirio/nirio_fifo.ipp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'host/include') diff --git a/host/include/uhd/transport/nirio/nirio_fifo.ipp b/host/include/uhd/transport/nirio/nirio_fifo.ipp index 80a0c2a89..48800f75b 100644 --- a/host/include/uhd/transport/nirio/nirio_fifo.ipp +++ b/host/include/uhd/transport/nirio/nirio_fifo.ipp @@ -110,6 +110,8 @@ nirio_status nirio_fifo::start() in.function = nirio_driver_iface::NIRIO_FUNC::FIFO; in.subfunction = nirio_driver_iface::NIRIO_FIFO::START; + in.params.fifo.channel = _fifo_channel; + status = _riok_proxy_ptr->sync_operation(&in, sizeof(in), &out, sizeof(out)); if (nirio_status_not_fatal(status)) { _acquired_pending = 0; @@ -133,6 +135,8 @@ nirio_status nirio_fifo::stop() in.function = nirio_driver_iface::NIRIO_FUNC::FIFO; in.subfunction = nirio_driver_iface::NIRIO_FIFO::STOP; + in.params.fifo.channel = _fifo_channel; + status = _riok_proxy_ptr->sync_operation(&in, sizeof(in), &out, sizeof(out)); return status; -- cgit v1.2.3 From 443982a8c18bc8628584f75068133577e15751e5 Mon Sep 17 00:00:00 2001 From: Ashish Chaudhari Date: Wed, 9 Apr 2014 12:56:12 -0700 Subject: nirio: Enhancement: Added state to nirio_fifo to avoid unnecessary kernel calls for redundant transitions. --- host/include/uhd/transport/nirio/nirio_fifo.h | 6 +- host/include/uhd/transport/nirio/nirio_fifo.ipp | 93 ++++++++++++++++--------- 2 files changed, 64 insertions(+), 35 deletions(-) (limited to 'host/include') diff --git a/host/include/uhd/transport/nirio/nirio_fifo.h b/host/include/uhd/transport/nirio/nirio_fifo.h index f7abb396f..fc1de245d 100644 --- a/host/include/uhd/transport/nirio/nirio_fifo.h +++ b/host/include/uhd/transport/nirio/nirio_fifo.h @@ -104,16 +104,20 @@ public: uint32_t& num_remaining); private: //Methods - bool _is_initialized(); datatype_info_t _get_datatype_info(); nirio_status _get_transfer_count(uint64_t& transfer_count); nirio_status _ensure_transfer_completed(uint32_t timeout_ms); private: //Members + enum fifo_state_t { + UNMAPPED, MAPPED, STARTED + }; + std::string _name; fifo_direction_t _fifo_direction; uint32_t _fifo_channel; datatype_info_t _datatype_info; + fifo_state_t _state; size_t _acquired_pending; nirio_driver_iface::rio_mmap_t _mem_map; boost::recursive_mutex _mutex; diff --git a/host/include/uhd/transport/nirio/nirio_fifo.ipp b/host/include/uhd/transport/nirio/nirio_fifo.ipp index 48800f75b..1c593ef3c 100644 --- a/host/include/uhd/transport/nirio/nirio_fifo.ipp +++ b/host/include/uhd/transport/nirio/nirio_fifo.ipp @@ -31,6 +31,7 @@ nirio_fifo::nirio_fifo( _fifo_direction(direction), _fifo_channel(fifo_instance), _datatype_info(_get_datatype_info()), + _state(UNMAPPED), _acquired_pending(0), _mem_map(), _riok_proxy_ptr(&riok_proxy), @@ -61,28 +62,36 @@ nirio_status nirio_fifo::initialize( if (!_riok_proxy_ptr) return NiRio_Status_ResourceNotInitialized; boost::unique_lock lock(_mutex); - nirio_driver_iface::nirio_syncop_in_params_t in = {}; - nirio_driver_iface::nirio_syncop_out_params_t out = {}; + if (_state == UNMAPPED) { + nirio_driver_iface::nirio_syncop_in_params_t in = {}; + nirio_driver_iface::nirio_syncop_out_params_t out = {}; - //Forcefully stop the fifo if it is running - in.function = nirio_driver_iface::NIRIO_FUNC::FIFO; - in.subfunction = nirio_driver_iface::NIRIO_FIFO::STOP; - status = _riok_proxy_ptr->sync_operation(&in, sizeof(in), &out, sizeof(out)); + //Forcefully stop the fifo if it is running + in.function = nirio_driver_iface::NIRIO_FUNC::FIFO; + in.subfunction = nirio_driver_iface::NIRIO_FIFO::STOP; + status = _riok_proxy_ptr->sync_operation(&in, sizeof(in), &out, sizeof(out)); - in.function = nirio_driver_iface::NIRIO_FUNC::FIFO; - in.subfunction = nirio_driver_iface::NIRIO_FIFO::CONFIGURE; + in.function = nirio_driver_iface::NIRIO_FUNC::FIFO; + in.subfunction = nirio_driver_iface::NIRIO_FIFO::CONFIGURE; - in.params.fifo.channel = _fifo_channel; - in.params.fifo.op.config.requestedDepth = static_cast(requested_depth); - in.params.fifo.op.config.requiresActuals = 1; + in.params.fifo.channel = _fifo_channel; + in.params.fifo.op.config.requestedDepth = static_cast(requested_depth); + in.params.fifo.op.config.requiresActuals = 1; - status = _riok_proxy_ptr->sync_operation(&in, sizeof(in), &out, sizeof(out)); - if (nirio_status_fatal(status)) return status; + status = _riok_proxy_ptr->sync_operation(&in, sizeof(in), &out, sizeof(out)); + if (nirio_status_fatal(status)) return status; - actual_depth = out.params.fifo.op.config.actualDepth; - actual_size = out.params.fifo.op.config.actualSize; + actual_depth = out.params.fifo.op.config.actualDepth; + actual_size = out.params.fifo.op.config.actualSize; - status = _riok_proxy_ptr->map_fifo_memory(_fifo_channel, actual_size, _mem_map); + status = _riok_proxy_ptr->map_fifo_memory(_fifo_channel, actual_size, _mem_map); + + if (nirio_status_not_fatal(status)) { + _state = MAPPED; + } + } else { + status = NiRio_Status_SoftwareFault; + } return status; } @@ -90,9 +99,13 @@ template void nirio_fifo::finalize() { boost::unique_lock lock(_mutex); - if (!_mem_map.is_null()) { - stop(); + + //If the FIFO is started, the stop will change the state to MAPPED. + stop(); + + if (_state == MAPPED) { _riok_proxy_ptr->unmap_fifo_memory(_mem_map); + _state = UNMAPPED; //Assume teardown succeeded } } @@ -104,18 +117,25 @@ nirio_status nirio_fifo::start() boost::unique_lock lock(_mutex); - nirio_driver_iface::nirio_syncop_in_params_t in = {}; - nirio_driver_iface::nirio_syncop_out_params_t out = {}; + if (_state == STARTED) { + //Do nothing. Already started. + } else if (_state == MAPPED) { + nirio_driver_iface::nirio_syncop_in_params_t in = {}; + nirio_driver_iface::nirio_syncop_out_params_t out = {}; - in.function = nirio_driver_iface::NIRIO_FUNC::FIFO; - in.subfunction = nirio_driver_iface::NIRIO_FIFO::START; + in.function = nirio_driver_iface::NIRIO_FUNC::FIFO; + in.subfunction = nirio_driver_iface::NIRIO_FIFO::START; - in.params.fifo.channel = _fifo_channel; + in.params.fifo.channel = _fifo_channel; - status = _riok_proxy_ptr->sync_operation(&in, sizeof(in), &out, sizeof(out)); - if (nirio_status_not_fatal(status)) { - _acquired_pending = 0; - _expected_xfer_count = 0; + status = _riok_proxy_ptr->sync_operation(&in, sizeof(in), &out, sizeof(out)); + if (nirio_status_not_fatal(status)) { + _state = STARTED; + _acquired_pending = 0; + _expected_xfer_count = 0; + } + } else { + status = NiRio_Status_ResourceNotInitialized; } return status; } @@ -127,17 +147,22 @@ nirio_status nirio_fifo::stop() if (!_riok_proxy_ptr) return NiRio_Status_ResourceNotInitialized; boost::unique_lock lock(_mutex); - if (_acquired_pending > 0) release(_acquired_pending); - nirio_driver_iface::nirio_syncop_in_params_t in = {}; - nirio_driver_iface::nirio_syncop_out_params_t out = {}; + if (_state == STARTED) { + if (_acquired_pending > 0) release(_acquired_pending); - in.function = nirio_driver_iface::NIRIO_FUNC::FIFO; - in.subfunction = nirio_driver_iface::NIRIO_FIFO::STOP; + nirio_driver_iface::nirio_syncop_in_params_t in = {}; + nirio_driver_iface::nirio_syncop_out_params_t out = {}; - in.params.fifo.channel = _fifo_channel; + in.function = nirio_driver_iface::NIRIO_FUNC::FIFO; + in.subfunction = nirio_driver_iface::NIRIO_FIFO::STOP; - status = _riok_proxy_ptr->sync_operation(&in, sizeof(in), &out, sizeof(out)); + in.params.fifo.channel = _fifo_channel; + + status = _riok_proxy_ptr->sync_operation(&in, sizeof(in), &out, sizeof(out)); + + _state = MAPPED; //Assume teardown succeeded + } return status; } -- cgit v1.2.3 From d9d16bd0c5aa905dd2737b708969c24bf151a73f Mon Sep 17 00:00:00 2001 From: Ashish Chaudhari Date: Wed, 9 Apr 2014 13:01:54 -0700 Subject: nirio: Removed RX zero-copy workaround for NI-RIO 13.0 --- host/include/uhd/transport/nirio/nirio_quirks.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'host/include') diff --git a/host/include/uhd/transport/nirio/nirio_quirks.h b/host/include/uhd/transport/nirio/nirio_quirks.h index 326eeeb8c..ed4f72e7f 100644 --- a/host/include/uhd/transport/nirio/nirio_quirks.h +++ b/host/include/uhd/transport/nirio/nirio_quirks.h @@ -24,8 +24,8 @@ //Quirk#1: We need to verify RX zero-copy data transfers from the RIO // driver if we are in full duplex mode. -// This option allows disabling this quirk by compiling it out. -#define UHD_NIRIO_RX_FIFO_XFER_CHECK_EN 1 +// This option allows enabling this quirk. +#define UHD_NIRIO_RX_FIFO_XFER_CHECK_EN 0 namespace uhd { namespace niusrprio { -- cgit v1.2.3 From 6157961a070f9c5683f7a04620fc784118dc3028 Mon Sep 17 00:00:00 2001 From: Ashish Chaudhari Date: Wed, 9 Apr 2014 15:26:42 -0700 Subject: review#64288: Addressed Patrick's feedback --- host/include/uhd/transport/nirio/nirio_fifo.ipp | 139 +++++++++++++----------- 1 file changed, 78 insertions(+), 61 deletions(-) (limited to 'host/include') diff --git a/host/include/uhd/transport/nirio/nirio_fifo.ipp b/host/include/uhd/transport/nirio/nirio_fifo.ipp index 1c593ef3c..437e3a1fc 100644 --- a/host/include/uhd/transport/nirio/nirio_fifo.ipp +++ b/host/include/uhd/transport/nirio/nirio_fifo.ipp @@ -69,16 +69,17 @@ nirio_status nirio_fifo::initialize( //Forcefully stop the fifo if it is running in.function = nirio_driver_iface::NIRIO_FUNC::FIFO; in.subfunction = nirio_driver_iface::NIRIO_FIFO::STOP; - status = _riok_proxy_ptr->sync_operation(&in, sizeof(in), &out, sizeof(out)); + in.params.fifo.channel = _fifo_channel; + _riok_proxy_ptr->sync_operation(&in, sizeof(in), &out, sizeof(out)); //Cleanup operation. Ignore status. + //Configure the FIFO now that we know it is stopped in.function = nirio_driver_iface::NIRIO_FUNC::FIFO; in.subfunction = nirio_driver_iface::NIRIO_FIFO::CONFIGURE; - in.params.fifo.channel = _fifo_channel; in.params.fifo.op.config.requestedDepth = static_cast(requested_depth); in.params.fifo.op.config.requiresActuals = 1; - status = _riok_proxy_ptr->sync_operation(&in, sizeof(in), &out, sizeof(out)); + if (nirio_status_fatal(status)) return status; actual_depth = out.params.fifo.op.config.actualDepth; @@ -180,36 +181,40 @@ nirio_status nirio_fifo::acquire( boost::unique_lock lock(_mutex); - nirio_driver_iface::nirio_syncop_in_params_t in = {}; - uint32_t stuffed[2]; - nirio_driver_iface::nirio_syncop_out_params_t out = {}; - init_syncop_out_params(out, stuffed, sizeof(stuffed)); + if (_state == STARTED) { + nirio_driver_iface::nirio_syncop_in_params_t in = {}; + uint32_t stuffed[2]; + nirio_driver_iface::nirio_syncop_out_params_t out = {}; + init_syncop_out_params(out, stuffed, sizeof(stuffed)); - in.function = nirio_driver_iface::NIRIO_FUNC::FIFO; - in.subfunction = nirio_driver_iface::NIRIO_FIFO::WAIT; + in.function = nirio_driver_iface::NIRIO_FUNC::FIFO; + in.subfunction = nirio_driver_iface::NIRIO_FIFO::WAIT; - in.params.fifo.channel = _fifo_channel; - in.params.fifo.op.wait.elementsRequested = static_cast(elements_requested); - in.params.fifo.op.wait.scalarType = static_cast(_datatype_info.scalar_type); - in.params.fifo.op.wait.bitWidth = _datatype_info.width * 8; - in.params.fifo.op.wait.output = _fifo_direction == OUTPUT_FIFO; - in.params.fifo.op.wait.timeout = timeout; + in.params.fifo.channel = _fifo_channel; + in.params.fifo.op.wait.elementsRequested = static_cast(elements_requested); + in.params.fifo.op.wait.scalarType = static_cast(_datatype_info.scalar_type); + in.params.fifo.op.wait.bitWidth = _datatype_info.width * 8; + in.params.fifo.op.wait.output = _fifo_direction == OUTPUT_FIFO; + in.params.fifo.op.wait.timeout = timeout; - status = _riok_proxy_ptr->sync_operation(&in, sizeof(in), &out, sizeof(out)); + status = _riok_proxy_ptr->sync_operation(&in, sizeof(in), &out, sizeof(out)); - if (nirio_status_not_fatal(status)) { - elements = static_cast(out.params.fifo.op.wait.elements.pointer); - elements_acquired = stuffed[0]; - elements_remaining = stuffed[1]; - _acquired_pending = elements_acquired; - - if (UHD_NIRIO_RX_FIFO_XFER_CHECK_EN && - _riok_proxy_ptr->get_rio_quirks().rx_fifo_xfer_check_en() && - get_direction() == INPUT_FIFO - ) { - _expected_xfer_count += static_cast(elements_requested * sizeof(data_t)); - status = _ensure_transfer_completed(timeout); + if (nirio_status_not_fatal(status)) { + elements = static_cast(out.params.fifo.op.wait.elements.pointer); + elements_acquired = stuffed[0]; + elements_remaining = stuffed[1]; + _acquired_pending = elements_acquired; + + if (UHD_NIRIO_RX_FIFO_XFER_CHECK_EN && + _riok_proxy_ptr->get_rio_quirks().rx_fifo_xfer_check_en() && + get_direction() == INPUT_FIFO + ) { + _expected_xfer_count += static_cast(elements_requested * sizeof(data_t)); + status = _ensure_transfer_completed(timeout); + } } + } else { + status = NiRio_Status_ResourceNotInitialized; } return status; @@ -223,17 +228,21 @@ nirio_status nirio_fifo::release(const size_t elements) boost::unique_lock lock(_mutex); - nirio_driver_iface::nirio_syncop_in_params_t in = {}; - nirio_driver_iface::nirio_syncop_out_params_t out = {}; + if (_state == STARTED) { + nirio_driver_iface::nirio_syncop_in_params_t in = {}; + nirio_driver_iface::nirio_syncop_out_params_t out = {}; - in.function = nirio_driver_iface::NIRIO_FUNC::FIFO; - in.subfunction = nirio_driver_iface::NIRIO_FIFO::GRANT; + in.function = nirio_driver_iface::NIRIO_FUNC::FIFO; + in.subfunction = nirio_driver_iface::NIRIO_FIFO::GRANT; - in.params.fifo.channel = _fifo_channel; - in.params.fifo.op.grant.elements = static_cast(elements); + in.params.fifo.channel = _fifo_channel; + in.params.fifo.op.grant.elements = static_cast(elements); - status = _riok_proxy_ptr->sync_operation(&in, sizeof(in), &out, sizeof(out)); - _acquired_pending = 0; + status = _riok_proxy_ptr->sync_operation(&in, sizeof(in), &out, sizeof(out)); + _acquired_pending = 0; + } else { + status = NiRio_Status_ResourceNotInitialized; + } return status; } @@ -251,23 +260,27 @@ nirio_status nirio_fifo::read( boost::unique_lock lock(_mutex); - nirio_driver_iface::nirio_syncop_in_params_t in = {}; - nirio_driver_iface::nirio_syncop_out_params_t out = {}; - init_syncop_out_params(out, buf, num_elements * _datatype_info.width); + if (_state == STARTED) { + nirio_driver_iface::nirio_syncop_in_params_t in = {}; + nirio_driver_iface::nirio_syncop_out_params_t out = {}; + init_syncop_out_params(out, buf, num_elements * _datatype_info.width); - in.function = nirio_driver_iface::NIRIO_FUNC::FIFO; - in.subfunction = nirio_driver_iface::NIRIO_FIFO::READ; + in.function = nirio_driver_iface::NIRIO_FUNC::FIFO; + in.subfunction = nirio_driver_iface::NIRIO_FIFO::READ; - in.params.fifo.channel = _fifo_channel; - in.params.fifo.op.readWithDataType.timeout = timeout; - in.params.fifo.op.readWithDataType.scalarType = static_cast(_datatype_info.scalar_type); - in.params.fifo.op.readWithDataType.bitWidth = _datatype_info.width * 8; + in.params.fifo.channel = _fifo_channel; + in.params.fifo.op.readWithDataType.timeout = timeout; + in.params.fifo.op.readWithDataType.scalarType = static_cast(_datatype_info.scalar_type); + in.params.fifo.op.readWithDataType.bitWidth = _datatype_info.width * 8; - status = _riok_proxy_ptr->sync_operation(&in, sizeof(in), &out, sizeof(out)); + status = _riok_proxy_ptr->sync_operation(&in, sizeof(in), &out, sizeof(out)); - if (nirio_status_not_fatal(status) || status == NiRio_Status_FifoTimeout) { - num_read = out.params.fifo.op.read.numberRead; - num_remaining = out.params.fifo.op.read.numberRemaining; + if (nirio_status_not_fatal(status) || status == NiRio_Status_FifoTimeout) { + num_read = out.params.fifo.op.read.numberRead; + num_remaining = out.params.fifo.op.read.numberRemaining; + } + } else { + status = NiRio_Status_ResourceNotInitialized; } return status; @@ -285,22 +298,26 @@ nirio_status nirio_fifo::write( boost::unique_lock lock(_mutex); - nirio_driver_iface::nirio_syncop_in_params_t in = {}; - init_syncop_in_params(in, buf, num_elements * _datatype_info.width); - nirio_driver_iface::nirio_syncop_out_params_t out = {}; + if (_state == STARTED) { + nirio_driver_iface::nirio_syncop_in_params_t in = {}; + init_syncop_in_params(in, buf, num_elements * _datatype_info.width); + nirio_driver_iface::nirio_syncop_out_params_t out = {}; - in.function = nirio_driver_iface::NIRIO_FUNC::FIFO; - in.subfunction = nirio_driver_iface::NIRIO_FIFO::WRITE; + in.function = nirio_driver_iface::NIRIO_FUNC::FIFO; + in.subfunction = nirio_driver_iface::NIRIO_FIFO::WRITE; - in.params.fifo.channel = _fifo_channel; - in.params.fifo.op.writeWithDataType.timeout = timeout; - in.params.fifo.op.readWithDataType.scalarType = static_cast(_datatype_info.scalar_type); - in.params.fifo.op.readWithDataType.bitWidth = _datatype_info.width * 8; + in.params.fifo.channel = _fifo_channel; + in.params.fifo.op.writeWithDataType.timeout = timeout; + in.params.fifo.op.readWithDataType.scalarType = static_cast(_datatype_info.scalar_type); + in.params.fifo.op.readWithDataType.bitWidth = _datatype_info.width * 8; - status = _riok_proxy_ptr->sync_operation(&in, sizeof(in), &out, sizeof(out)); + status = _riok_proxy_ptr->sync_operation(&in, sizeof(in), &out, sizeof(out)); - if (nirio_status_not_fatal(status) || status == NiRio_Status_FifoTimeout) { - num_remaining = out.params.fifo.op.write.numberRemaining; + if (nirio_status_not_fatal(status) || status == NiRio_Status_FifoTimeout) { + num_remaining = out.params.fifo.op.write.numberRemaining; + } + } else { + status = NiRio_Status_ResourceNotInitialized; } return status; -- cgit v1.2.3