diff --git a/Inc/FreeRTOSConfig.h b/Inc/FreeRTOSConfig.h index 755e468..1663f5a 100644 --- a/Inc/FreeRTOSConfig.h +++ b/Inc/FreeRTOSConfig.h @@ -59,7 +59,7 @@ #define configTICK_RATE_HZ ((TickType_t)1000) #define configMAX_PRIORITIES ( 7 ) #define configMINIMAL_STACK_SIZE ((uint16_t)128) -#define configTOTAL_HEAP_SIZE ((size_t)3072) +#define configTOTAL_HEAP_SIZE ((size_t)2048) #define configMAX_TASK_NAME_LEN ( 16 ) #define configUSE_16_BIT_TICKS 0 #define configUSE_MUTEXES 1 diff --git a/STM32L433CCUx_FLASH.ld b/STM32L433CCUx_FLASH.ld index f05aa52..457b692 100644 --- a/STM32L433CCUx_FLASH.ld +++ b/STM32L433CCUx_FLASH.ld @@ -4,7 +4,7 @@ ENTRY(Reset_Handler) /* Highest address of the user mode stack */ _estack = 0x2000C000; /* end of RAM */ /* Generate a link error if heap and stack don't fit into RAM */ -_Min_Heap_Size = 0x400; /* required amount of heap */ +_Min_Heap_Size = 0x800; /* required amount of heap */ _Min_Stack_Size = 0x400; /* required amount of stack */ /* Specify the memory areas */ diff --git a/Src/main.c b/Src/main.c index b2aa90a..5d03a85 100644 --- a/Src/main.c +++ b/Src/main.c @@ -1662,6 +1662,12 @@ void assert_failed(uint8_t* file, uint32_t line) } #endif /* USE_FULL_ASSERT */ +void vApplicationMallocFailedHook() +{ + snprintf(error_message, sizeof(error_message), "malloc failed"); + while (1); +} + void vApplicationStackOverflowHook(TaskHandle_t xTask, signed char *pcTaskName) { snprintf(error_message, sizeof(error_message), "stack overflow %s", pcTaskName); diff --git a/TNC/HdlcFrame.cpp b/TNC/HdlcFrame.cpp index a101a7c..3ce60ef 100644 --- a/TNC/HdlcFrame.cpp +++ b/TNC/HdlcFrame.cpp @@ -17,12 +17,14 @@ IoFramePool& ioFramePool() { void release(IoFrame* frame) { ioFramePool().release(frame); +// printf("< %d\r\n", ioFramePool().size()); } IoFrame* acquire() { auto result = ioFramePool().acquire(); if (result == nullptr) CxxErrorHandler(); +// printf("> %d\r\n", ioFramePool().size()); return result; } @@ -33,6 +35,7 @@ IoFrame* acquire_wait() while ((result = ioFramePool().acquire()) == nullptr) { osThreadYield(); } +// printf("> %d\r\n", ioFramePool().size()); return result; } diff --git a/TNC/HdlcFrame.hpp b/TNC/HdlcFrame.hpp index d37dea5..5aa919c 100644 --- a/TNC/HdlcFrame.hpp +++ b/TNC/HdlcFrame.hpp @@ -170,12 +170,10 @@ 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); diff --git a/TNC/KissHardware.cpp b/TNC/KissHardware.cpp index aa8a4f9..7ce1305 100644 --- a/TNC/KissHardware.cpp +++ b/TNC/KissHardware.cpp @@ -43,10 +43,10 @@ int powerOffViaUSB(void) namespace mobilinkd { namespace tnc { namespace kiss { #ifdef NUCLEOTNC -const char FIRMWARE_VERSION[] = "2.1.8"; +const char FIRMWARE_VERSION[] = "2.1.9"; const char HARDWARE_VERSION[] = "Mobilinkd NucleoTNC"; #else -const char FIRMWARE_VERSION[] = "2.1.8"; +const char FIRMWARE_VERSION[] = "2.1.9"; const char HARDWARE_VERSION[] = "Mobilinkd TNC3 2.1.1"; #endif diff --git a/TNC/M17Encoder.cpp b/TNC/M17Encoder.cpp index 85a0819..0e91573 100644 --- a/TNC/M17Encoder.cpp +++ b/TNC/M17Encoder.cpp @@ -152,6 +152,13 @@ void M17Encoder::run() osThreadSuspend(encoderTaskHandle); } +/** + * + * @param frame is the frame to transmit. Ownership has been transferred + * and this function is responsible for either transferring ownership + * downstream or releasing it. + * @param type is whether this is a basic packet or encapsulated packet. + */ void M17Encoder::process_packet(tnc::hdlc::IoFrame* frame, FrameType type) { using namespace mobilinkd::tnc::kiss; @@ -189,6 +196,7 @@ void M17Encoder::process_packet(tnc::hdlc::IoFrame* frame, FrameType type) default: ERROR("M17 encoder bad state"); } + release(frame); } void M17Encoder::process_stream(tnc::hdlc::IoFrame* frame, FrameType type) diff --git a/TNC/SerialPort.cpp b/TNC/SerialPort.cpp index d270ed5..cf306e1 100644 --- a/TNC/SerialPort.cpp +++ b/TNC/SerialPort.cpp @@ -139,12 +139,11 @@ void startSerialTask(void const* arg) if (evt.value.v < FLASH_BASE) // Assumes FLASH_BASE < SRAM_BASE. { // Error received. - hdlc::release(frame); + frame->clear(); #ifndef NUCLEOTNC ERROR("UART Error: %08lx", uart_error.load()); #endif uart_error.store(HAL_UART_ERROR_NONE); - frame = hdlc::acquire_wait(); HAL_UART_Receive_DMA(&huart_serial, rxBuffer, RX_BUFFER_SIZE * 2); __HAL_UART_ENABLE_IT(&huart_serial, UART_IT_IDLE); continue; @@ -183,6 +182,7 @@ void startSerialTask(void const* arg) if (hdlc::ioFramePool().size() < (hdlc::ioFramePool().capacity() / 4)) { UART_DMAPauseReceive(&huart_serial); + WARN("frame pool low"); while (hdlc::ioFramePool().size() < (hdlc::ioFramePool().capacity() / 2)) { osThreadYield(); @@ -206,22 +206,19 @@ void startSerialTask(void const* arg) switch (c) { case TFESC: if (not frame->push_back(FESC)) { - hdlc::release(frame); + frame->clear(); state = WAIT_FBEGIN; // Drop frame; - frame = hdlc::acquire_wait(); } break; case TFEND: if (not frame->push_back(FEND)) { - hdlc::release(frame); + frame->clear(); state = WAIT_FBEGIN; // Drop frame; - frame = hdlc::acquire_wait(); } break; default: - hdlc::release(frame); + frame->clear(); state = WAIT_FBEGIN; // Drop frame; - frame = hdlc::acquire_wait(); } break; }