@@ -68,7 +68,12 @@ void NfcManager::initAuthPrecompute() {
6868 xQueueSend (m_authCtxFreeQueue, &item, 0 );
6969 }
7070
71- BaseType_t ok = xTaskCreateUniversal (authPrecomputeTaskEntry, " hk_auth_precompute" , 4096 , this , 3 , &m_authPrecomputeTaskHandle, 0 );
71+ // 8192, not 4096: constructing a DDKAuthenticationContext runs mbedTLS P-256
72+ // key generation. Measured usage is 4056-4288 bytes and varies with the
73+ // random key material, so a 4096-byte stack left as little as 40 bytes of
74+ // headroom and intermittently overflowed -- panicking mid-transaction, which
75+ // the phone reported as a protocol error.
76+ BaseType_t ok = xTaskCreateUniversal (authPrecomputeTaskEntry, " hk_auth_precompute" , kAuthPrecomputeStackBytes , this , 3 , &m_authPrecomputeTaskHandle, 0 );
7277 if (ok != pdPASS || !m_authPrecomputeTaskHandle) {
7378 ESP_LOGE (TAG , " Failed to start auth precompute task." );
7479 m_authPrecomputeTaskHandle = nullptr ;
@@ -160,6 +165,23 @@ void NfcManager::authPrecomputeTask() {
160165 const auto durationMs =
161166 std::chrono::duration_cast<std::chrono::milliseconds>(stopTime - startTime).count ();
162167
168+
169+ // Constructing the context runs mbedTLS P-256 key generation. Report the
170+ // headroom straight after: an overflow here reboots the device mid-
171+ // transaction, which is indistinguishable from a hang in the logs unless
172+ // the reset reason is checked at boot.
173+ {
174+ const UBaseType_t freeWords = uxTaskGetStackHighWaterMark (nullptr );
175+ const unsigned freeBytes = (unsigned )(freeWords * sizeof (StackType_t));
176+ if (freeBytes < 768 ) {
177+ ESP_LOGE (TAG , " precompute task stack CRITICALLY LOW: %u bytes free of %u" ,
178+ freeBytes, (unsigned )kAuthPrecomputeStackBytes );
179+ } else {
180+ ESP_LOGD (TAG , " precompute task stack headroom: %u bytes free of %u" , freeBytes,
181+ (unsigned )kAuthPrecomputeStackBytes );
182+ }
183+ }
184+
163185 if (!item->ctx ) {
164186 ESP_LOGE (TAG , " Auth precompute: allocation failed." );
165187 xQueueSend (m_authCtxFreeQueue, &item, 0 );
@@ -445,6 +467,21 @@ void NfcManager::handleTagPresence(const std::vector<uint8_t>& uid, const std::a
445467
446468 auto stopTime = std::chrono::high_resolution_clock::now ();
447469 ESP_LOGI (TAG , " Total processing time: %lli ms" , std::chrono::duration_cast<std::chrono::milliseconds>(stopTime - startTime).count ());
470+ // Headroom check. This task runs mbedTLS P-256 operations (ECDH, ECDSA) on
471+ // top of the reader's frame buffers, and an overflow here would look
472+ // exactly like the observed symptom: a reboot part-way through a
473+ // transaction. Reported every time so a downward trend is visible.
474+ const UBaseType_t stackFreeWords = uxTaskGetStackHighWaterMark (nullptr );
475+ if (stackFreeWords < 512 ) {
476+ ESP_LOGW (TAG , " nfc task stack headroom LOW: %u bytes free" ,
477+ (unsigned )(stackFreeWords * sizeof (StackType_t)));
478+ } else {
479+ ESP_LOGD (TAG , " nfc task stack headroom: %u bytes free" ,
480+ (unsigned )(stackFreeWords * sizeof (StackType_t)));
481+ }
482+ ESP_LOGD (TAG , " heap: %u free, %u min-ever" , (unsigned )esp_get_free_heap_size (),
483+ (unsigned )esp_get_minimum_free_heap_size ());
484+
448485}
449486
450487/* *
0 commit comments