diff --git a/.gitignore b/.gitignore index d3d6b6c..0ba9308 100644 --- a/.gitignore +++ b/.gitignore @@ -30,7 +30,15 @@ *.exe *.out *.app +*.elf +*.bin +*.map # TrueStudio Junk firmware.elf.launch *.s +_FLASH.ld +TrueSTUDIO/ +ARM_Debug/ +com.atollic* + diff --git a/.settings/com.atollic.truestudio.debug.hardware_device.prefs b/.settings/com.atollic.truestudio.debug.hardware_device.prefs deleted file mode 100644 index 01db2d9..0000000 --- a/.settings/com.atollic.truestudio.debug.hardware_device.prefs +++ /dev/null @@ -1,11 +0,0 @@ -BOARD=None -CODE_LOCATION=FLASH -ENDIAN=Little-endian -MCU=STM32L433CC -MCU_VENDOR=STMicroelectronics -MODEL=Lite -PROBE=ST-LINK -PROJECT_FORMAT_VERSION=2 -TARGET=ARM\u00AE -VERSION=4.1.0 -eclipse.preferences.version=1 diff --git a/README.md b/README.md index aa550e6..210a2b4 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,8 @@ This is the firmware for the TNC3 version 2.1.1 hardware. Use Eclipse with CDT and the GNU MCU Eclipse plugins. + + # Debugging Logging is enabled in debug builds and is output via ITM (SWO). The @@ -15,4 +17,5 @@ To read from this pipe, open a terminal and run: `while true; do tr -d '\01' < swv; done` If you change the MCU's core clock, you need to adjust the timing in the -`stlink-tnc3.cfg` config file. \ No newline at end of file +`stlink-tnc3.cfg` config file. + diff --git a/TNC/AfskDemodulator.cpp b/TNC/AfskDemodulator.cpp index a3d34d3..064ccdf 100644 --- a/TNC/AfskDemodulator.cpp +++ b/TNC/AfskDemodulator.cpp @@ -33,7 +33,7 @@ hdlc::IoFrame* Demodulator::operator()(float* samples, size_t len) // not enough bits in a block for more than one. if (result) { auto tmp = hdlc_decoder_(nrzi_.decode(bit), pll.locked); - if (tmp) hdlc::ioFramePool().release(tmp); + if (tmp) hdlc::release(tmp); } else { result = hdlc_decoder_(nrzi_.decode(bit), pll.locked); } diff --git a/TNC/AudioInput.cpp b/TNC/AudioInput.cpp index 07f0e47..b3ed7e5 100644 --- a/TNC/AudioInput.cpp +++ b/TNC/AudioInput.cpp @@ -465,11 +465,11 @@ void demodulatorTask() { last_fcs = save_fcs; last_counter = counter; } else { - hdlc::ioFramePool().release(frame); + hdlc::release(frame); } } else { - hdlc::ioFramePool().release(frame); + hdlc::release(frame); } } #endif @@ -483,11 +483,11 @@ void demodulatorTask() { last_fcs = save_fcs; last_counter = counter; } else { - hdlc::ioFramePool().release(frame); + hdlc::release(frame); } } else { - hdlc::ioFramePool().release(frame); + hdlc::release(frame); } } #endif @@ -501,11 +501,11 @@ void demodulatorTask() { last_fcs = save_fcs; last_counter = counter; } else { - hdlc::ioFramePool().release(frame); + hdlc::release(frame); } } else { - hdlc::ioFramePool().release(frame); + hdlc::release(frame); } } #endif diff --git a/TNC/HdlcDecoder.cpp b/TNC/HdlcDecoder.cpp index dbbd251..1ecace1 100644 --- a/TNC/HdlcDecoder.cpp +++ b/TNC/HdlcDecoder.cpp @@ -7,7 +7,7 @@ namespace mobilinkd { namespace tnc { namespace hdlc { Decoder::Decoder(bool pass_all) -: state_(SEARCH), ones_(0), buffer_(0), frame_(ioFramePool().acquire()) +: state_(SEARCH), ones_(0), buffer_(0), frame_(acquire()) , bits_(0), passall_(pass_all), ready_(false) {} @@ -17,7 +17,7 @@ IoFrame* Decoder::operator()(bool bit, bool pll) // It appears that the ioFramePool may not get initialized in the proper // order during some builds. - if (nullptr == frame_) frame_ = ioFramePool().acquire(); + if (nullptr == frame_) frame_ = acquire(); if (nullptr == frame_) return result; if (not pll) { @@ -26,7 +26,7 @@ IoFrame* Decoder::operator()(bool bit, bool pll) if (passall_ or frame_->ok()) { result = frame_; ready_ = false; - frame_ = ioFramePool().acquire(); + frame_ = acquire(); return result; } } @@ -37,7 +37,7 @@ IoFrame* Decoder::operator()(bool bit, bool pll) frame_->parse_fcs(); if (passall_ or frame_->ok()) { result = frame_; - frame_ = ioFramePool().acquire(); + frame_ = acquire(); return result; } frame_->clear(); diff --git a/TNC/HdlcDecoder.hpp b/TNC/HdlcDecoder.hpp index 20e8120..a8324ad 100644 --- a/TNC/HdlcDecoder.hpp +++ b/TNC/HdlcDecoder.hpp @@ -283,7 +283,7 @@ struct Decoder #if 0 Decoder::Decoder(bool pass_all) -: state_(SEARCH), ones_(0), buffer_(0), frame_(ioFramePool().acquire()) +: state_(SEARCH), ones_(0), buffer_(0), frame_(acquire()) , bits_(0), passall_(pass_all), ready_(false) {} @@ -293,7 +293,7 @@ IoFrame* Decoder::operator()(bool bit, bool pll) // It appears that the ioFramePool may not get initialized in the proper // order during some builds. - if (nullptr == frame_) frame_ = ioFramePool().acquire(); + if (nullptr == frame_) frame_ = acquire(); if (not pll) { if ((state_ == FRAMING) and (frame_->size() > 17) and passall_) { @@ -301,7 +301,7 @@ IoFrame* Decoder::operator()(bool bit, bool pll) if (passall_ or frame_->ok()) { result = frame_; ready_ = false; - frame_ = ioFramePool().acquire(); + frame_ = acquire(); return result; } } @@ -312,7 +312,7 @@ IoFrame* Decoder::operator()(bool bit, bool pll) frame_->parse_fcs(); if (passall_ or frame_->ok()) { result = frame_; - frame_ = ioFramePool().acquire(); + frame_ = acquire(); return result; } frame_->clear(); diff --git a/TNC/HdlcFrame.cpp b/TNC/HdlcFrame.cpp index 6d411ac..5bfd2f1 100644 --- a/TNC/HdlcFrame.cpp +++ b/TNC/HdlcFrame.cpp @@ -2,6 +2,7 @@ // All rights reserved. #include "HdlcFrame.hpp" +#include "Log.h" namespace mobilinkd { namespace tnc { namespace hdlc { @@ -17,4 +18,11 @@ void release(IoFrame* frame) ioFramePool().release(frame); } +IoFrame* acquire() +{ + auto result = ioFramePool().acquire(); + if (result == nullptr) CxxErrorHandler(); + return result; +} + }}} // mobilinkd::tnc::hdlc diff --git a/TNC/HdlcFrame.hpp b/TNC/HdlcFrame.hpp index 5d91b77..aadf5a0 100644 --- a/TNC/HdlcFrame.hpp +++ b/TNC/HdlcFrame.hpp @@ -170,10 +170,12 @@ public: free_list_.pop_front(); } taskEXIT_CRITICAL_FROM_ISR(x); + DEBUG("Acquired frame %p (size after = %d)", result, free_list_.size()); return result; } void release(frame_type* frame) { + DEBUG("Released frame %p (size before = %d)", frame, free_list_.size()); frame->clear(); auto x = taskENTER_CRITICAL_FROM_ISR(); free_list_.push_back(*frame); @@ -195,13 +197,15 @@ IoFramePool& ioFramePool(void); * that causes functions using ioFramePool().release(frame) to use an * extremely large amount of stack space (4-6K vs. 24 bytes). * - * This function merely acts as some sort of firewall to the stack usage. + * This function merely acts as a compiler firewall to the stack usage. * It's own stack usage is minimal even though it is making the same call. * * @param frame */ void release(IoFrame* frame); +IoFrame* acquire(void); + }}} // mobilinkd::tnc::hdlc #endif // MOBILINKD__HDLC_FRAME_HPP_ diff --git a/TNC/NullPort.hpp b/TNC/NullPort.hpp index c3164e9..48941b6 100644 --- a/TNC/NullPort.hpp +++ b/TNC/NullPort.hpp @@ -40,7 +40,7 @@ struct NullPort : PortInterface } virtual bool write(hdlc::IoFrame* frame, uint32_t = osWaitForever) { - hdlc::ioFramePool().release(frame); + hdlc::release(frame); return true; } diff --git a/TNC/SerialPort.cpp b/TNC/SerialPort.cpp index b66066e..cb28190 100644 --- a/TNC/SerialPort.cpp +++ b/TNC/SerialPort.cpp @@ -56,7 +56,7 @@ extern "C" void startSerialTask(void const* arg) State state = WAIT_FBEGIN; - hdlc::IoFrame* frame = hdlc::ioFramePool().acquire(); + hdlc::IoFrame* frame = hdlc::acquire(); HAL_UART_Receive_IT(&huart3, &rxBuffer, 1); @@ -69,10 +69,10 @@ extern "C" void startSerialTask(void const* arg) } if (evt.value.v & 0x100) { - hdlc::ioFramePool().release(frame); + hdlc::release(frame); ERROR("UART Error: %08lx", evt.value.v); uart_error.store(HAL_UART_ERROR_NONE); - frame = hdlc::ioFramePool().acquire(); + frame = hdlc::acquire(); HAL_UART_Receive_IT(&huart3, &rxBuffer, 1); continue; } @@ -96,14 +96,14 @@ extern "C" void startSerialTask(void const* arg) DEBUG("Received frame of %d bytes", frame->size()); frame->source(hdlc::IoFrame::SERIAL_DATA); osMessagePut(ioEventQueueHandle, reinterpret_cast(frame), osWaitForever); - frame = hdlc::ioFramePool().acquire(); + frame = hdlc::acquire(); state = WAIT_FBEGIN; break; default: if (not frame->push_back(c)) { - hdlc::ioFramePool().release(frame); + hdlc::release(frame); state = WAIT_FBEGIN; // Drop frame; - frame = hdlc::ioFramePool().acquire(); + frame = hdlc::acquire(); } } break; @@ -112,22 +112,22 @@ extern "C" void startSerialTask(void const* arg) switch (c) { case TFESC: if (not frame->push_back(FESC)) { - hdlc::ioFramePool().release(frame); + hdlc::release(frame); state = WAIT_FBEGIN; // Drop frame; - frame = hdlc::ioFramePool().acquire(); + frame = hdlc::acquire(); } break; case TFEND: if (not frame->push_back(FEND)) { - hdlc::ioFramePool().release(frame); + hdlc::release(frame); state = WAIT_FBEGIN; // Drop frame; - frame = hdlc::ioFramePool().acquire(); + frame = hdlc::acquire(); } break; default: - hdlc::ioFramePool().release(frame); + hdlc::release(frame); state = WAIT_FBEGIN; // Drop frame; - frame = hdlc::ioFramePool().acquire(); + frame = hdlc::acquire(); } break; } diff --git a/TNC/UsbPort.cpp b/TNC/UsbPort.cpp index e52bcc1..5b714b1 100644 --- a/TNC/UsbPort.cpp +++ b/TNC/UsbPort.cpp @@ -16,7 +16,7 @@ extern osMessageQId ioEventQueueHandle; extern "C" void cdc_receive(const uint8_t* buf, uint32_t len) { using namespace mobilinkd::tnc::hdlc; if (mobilinkd::tnc::getUsbPort()->queue() != 0) { - auto frame = mobilinkd::tnc::hdlc::ioFramePool().acquire(); + auto frame = mobilinkd::tnc::hdlc::acquire(); if (frame) { for (uint32_t i = 0; i != len; ++i) { frame->push_back(*buf++); @@ -48,7 +48,7 @@ extern "C" void startCDCTask(void const* arg) State state = WAIT_FBEGIN; - hdlc::IoFrame* frame = hdlc::ioFramePool().acquire(); + hdlc::IoFrame* frame = hdlc::acquire(); while (true) { osEvent evt = osMessageGet(usbPort->queue(), osWaitForever); @@ -81,14 +81,14 @@ extern "C" void startCDCTask(void const* arg) case FEND: frame->source(hdlc::IoFrame::SERIAL_DATA); osMessagePut(ioEventQueueHandle, reinterpret_cast(frame), osWaitForever); - frame = hdlc::ioFramePool().acquire(); + frame = hdlc::acquire(); state = WAIT_FBEGIN; break; default: if (not frame->push_back(c)) { hdlc::release(frame); state = WAIT_FBEGIN; // Drop frame; - frame = hdlc::ioFramePool().acquire(); + frame = hdlc::acquire(); } } break; @@ -99,20 +99,20 @@ extern "C" void startCDCTask(void const* arg) if (not frame->push_back(FESC)) { hdlc::release(frame); state = WAIT_FBEGIN; // Drop frame; - frame = hdlc::ioFramePool().acquire(); + frame = hdlc::acquire(); } break; case TFEND: if (not frame->push_back(FEND)) { hdlc::release(frame); state = WAIT_FBEGIN; // Drop frame; - frame = hdlc::ioFramePool().acquire(); + frame = hdlc::acquire(); } break; default: hdlc::release(frame); state = WAIT_FBEGIN; // Drop frame; - frame = hdlc::ioFramePool().acquire(); + frame = hdlc::acquire(); } break; }