diff --git a/rims_app/prj.conf b/rims_app/prj.conf index 18e701bf896..dce83b24e2c 100644 --- a/rims_app/prj.conf +++ b/rims_app/prj.conf @@ -50,7 +50,7 @@ CONFIG_LOG_BACKEND_UART=n # Use UART for log output CONFIG_MAIN_STACK_SIZE=1500 # CONFIG_CRC=y -CONFIG_ASSERT=y +CONFIG_ASSERT=n #CONFIG_NUM_PREEMPT_PRIORITIES=0 diff --git a/rims_app/src/temperature_measurements.cpp b/rims_app/src/temperature_measurements.cpp index 09d8513854b..d0c1c379244 100644 --- a/rims_app/src/temperature_measurements.cpp +++ b/rims_app/src/temperature_measurements.cpp @@ -95,7 +95,7 @@ template void PB_encode_egress(const T &tempresp) { } void TemperatureSampler::take_sample() { - ULOG_DEBUG("Samples on ch %d, size %d", this->_channel, this->_samples.size()); + // ULOG_DEBUG("Samples on ch %d, size %d", this->_channel, this->_samples.size()); _samples.push_back(adc_take_sample()); } diff --git a/rims_app/src/uart.cpp b/rims_app/src/uart.cpp index f5650bac90d..ef7e4f3f962 100644 --- a/rims_app/src/uart.cpp +++ b/rims_app/src/uart.cpp @@ -60,50 +60,73 @@ void log_worker(struct k_work *work) { } // Global log work item + static struct k_work_log_data uart_log_work; +#ifdef RIMS_UART_PERF_COUNTERS +static std::size_t buffer_copy_wait{}; +static std::size_t isr_execution{}; +static std::chrono::nanoseconds tx_total{}; +static std::chrono::nanoseconds tx_crit{}; +#endif + AsyncUART::AsyncUART() { _dev = DEVICE_DT_GET(DT_NODELABEL(usart1)); + __ASSERT(device_is_ready(_dev), "device needs to be ready"); - auto ret = uart_irq_callback_user_data_set(_dev, AsyncUART::uartCallback, this); - if (ret < 0) { - throw uart_not_ready_error{}; // catch this somewhere?? - } + [[maybe_unused]] auto ret = uart_irq_callback_user_data_set(_dev, AsyncUART::uartCallback, this); + __ASSERT(ret >= 0, ""); uart_irq_rx_enable(_dev); } void AsyncUART::loop() { - if (!device_is_ready(_dev)) { - /// TODO throw? - return; // Exit if the UART device is not ready - } + __ASSERT(device_is_ready(_dev), "device needs to be ready"); while (1) { - std::this_thread::sleep_for(std::chrono::seconds{2}); + std::this_thread::sleep_for(std::chrono::seconds{10}); +#ifdef RIMS_UART_PERF_COUNTERS + ULOG_DEBUG(R"log(buffer_copy_wait : %d)log", buffer_copy_wait); + ULOG_DEBUG(R"log(tx_total : %lldus)log", tx_total.count() / 1000); + ULOG_DEBUG(R"log(tx_critical : %lldus)log", tx_crit.count() / 1000); + ULOG_DEBUG(R"log(isr number : %zu)log", isr_execution); +#endif } } -static std::size_t buffer_copy_wait {}; - // free function, only need to copy data to uart's TX_BUFFER and that's it void AsyncUART::transmit(AsyncUART *dev, std::span bytes) { +#ifdef RIMS_UART_PERF_COUNTERS + auto isr_start = std::chrono::high_resolution_clock::now(); + isr_execution++; +#endif if (bytes.empty()) return; __ASSERT(bytes.size_bytes() <= dev->tx_buffer.capacity(), "for now, all bytes needs to fir in tx buffer"); while (dev->tx_buffer.free() < bytes.size_bytes()) { +#ifdef RIMS_UART_PERF_COUNTERS buffer_copy_wait++; +#endif std::this_thread::sleep_for(std::chrono::microseconds{20}); } - + +#ifdef RIMS_UART_PERF_COUNTERS + auto crit_start = std::chrono::high_resolution_clock::now(); +#endif k_spinlock_key_t key = k_spin_lock(&dev->tx_lock); - + __ASSERT(dev->no_copyInProgress(), "multiple copies at the same time are not allowed"); // copy all data to TX dev->tx_buffer.put_n(bytes.data(), bytes.size()); // if disabled, enable tx interrupts if (not dev->tx_irq_enabled()) dev->tx_irq_enable(); - + k_spin_unlock(&dev->tx_lock, key); +#ifdef RIMS_UART_PERF_COUNTERS + auto crit_stop = std::chrono::high_resolution_clock::now(); + auto isr_stop = std::chrono::high_resolution_clock::now(); + tx_total += isr_stop - isr_start; + tx_crit += crit_stop - crit_start; +#endif } void AsyncUART::uartCallback(const device *dev, void *user_data) { @@ -144,11 +167,11 @@ void AsyncUART::readByteUart() { } // push_back returns last placed byte, if the byte is 0x00 we got end of frame else if (rxBuffer().push_back(rxByte()) == 0) { - if(rxBuffer().size()>1){ - processMessage(); - }else{ - rxBuffer().clean(); - } + if (rxBuffer().size() > 1) { + processMessage(); + } else { + rxBuffer().clean(); + } } } diff --git a/rims_app/src/uart.hpp b/rims_app/src/uart.hpp index 7559f80c461..54969ad1184 100644 --- a/rims_app/src/uart.hpp +++ b/rims_app/src/uart.hpp @@ -26,38 +26,12 @@ class AsyncUART { void loop(); static void transmit(AsyncUART *dev, std::span bytes); - static void workHandler(k_work *work); static void uartCallback(const struct device *dev, void *user_data); void uartISR(); - bool tx_irq_enabled() const { - return _txIrqEnabled; - } - void tx_irq_enable() { - _txIrqEnabled = true; - uart_irq_tx_enable(_dev); - } - void tx_irq_disable() { - _txIrqEnabled = false; - uart_irq_tx_disable(_dev); - } - - void beginCopy() { - _copyInProgress = true; - } - void endCopy() { - _copyInProgress = false; - } - constexpr bool copyInProgress() const { - return _copyInProgress; - } - constexpr bool no_copyInProgress() const { - return not _copyInProgress; - } - - const device *_dev; private: + const device *_dev; std::array rx_buffers; uint8_t _currentBufferIndex{}; bool _faultFlag = false; @@ -79,6 +53,31 @@ class AsyncUART { inline bool txHasByte() const; inline void txByte(uint8_t byte); // low level write byte to device + constexpr bool tx_irq_enabled() const { + return _txIrqEnabled; + } + void tx_irq_enable() { + _txIrqEnabled = true; + uart_irq_tx_enable(_dev); + } + void tx_irq_disable() { + uart_irq_tx_disable(_dev); + _txIrqEnabled = false; + } + + void beginCopy() { + _copyInProgress = true; + } + void endCopy() { + _copyInProgress = false; + } + constexpr bool copyInProgress() const { + return _copyInProgress; + } + constexpr bool no_copyInProgress() const { + return not _copyInProgress; + } + // exception handlers inline void handleRxNotReadyError(const uart_rx_not_ready_error &e); inline void handleRxBufferOverflowError(const uart_rx_buffer_overflow &e);