Unreliable lorawan_tx_finished callback and InstrFetchProhibited crash when waiting for TX complete #155
Unanswered
FabiooPereira
asked this question in
Q&A
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
Overview
I'm experiencing two related issues with the LoRaWan-Arduino library on a RAK3212 breakout board (ESP32-S3 + SX1262 LoRa transceiver):
LMH_UNCONFIRMED_MSG), even when the packet is successfully transmitted (appears in TTN).lmh_send_blocking(), or long delay), the device crashes withInstrFetchProhibitedpanic.The crash only happens when the main thread is still active during transmission (e.g., waiting for callback or using blocking send). If I queue the packet and go to deep sleep immediately, it works reliably but I lose confirmation that the packet was actually sent and sometimes the data is never sent.
Hardware & Setup
LMH_UNCONFIRMED_MSG(triedLMH_CONFIRMED_MSGtoo)This is my init function which works fine
`bool initLoRa() {
Serial.println("[LoRa] Initializing LoRa module...");
// 1. Initialize the RAK LoRa transceiver
if (lora_rak3112_init() != 0) {
Serial.println("[LoRa] Radio initialization failed!");
vSemaphoreDelete(join_semaphore);
join_semaphore = nullptr;
return false;
}
// 2. Set OTAA credentials from config.h
lmh_setDevEui((uint8_t *)node_device_eui);
lmh_setAppEui((uint8_t *)node_app_eui);
lmh_setAppKey((uint8_t *)node_app_key);
// 3. Register callbacks
lmh_callback_t callbacks = {
BoardGetBatteryLevel,
BoardGetUniqueId,
BoardGetRandomSeed,
lorawan_rx_handler,
lorawan_has_joined_handler,
lorawan_confirm_class_handler, // confirm_class_handler
lorawan_join_failed_handler,
lorawan_tx_finished_handler,
lorawan_tx_conf_finished_handler // tx_conf_finished
};
// 4. Set Parameters
lmh_param_t params = {
LORAWAN_ADR_ON,
LORAWAN_DEFAULT_DATARATE,
LORAWAN_PUBLIC_NETWORK,
JOIN_TRIALS, // join trials
LORAWAN_DEFAULT_TX_POWER,
LORAWAN_DUTYCYCLE_OFF
};
// 5. Initialize LoRaMAC layer
if (lmh_init(&callbacks, params, true, CLASS_A, LORA_REGION) != 0) {
Serial.println("[LoRa] lmh_init failed!");
return false;
}
// 6. Start the OTAA
Serial.println("[LoRa] Starting OTAA join...");
if (join_semaphore == nullptr) {
join_semaphore = xSemaphoreCreateBinary();
if (join_semaphore == nullptr) {
Serial.println("[LoRa] Failed to create join semaphore!");
return false;
}
}
lmh_join();
Serial.println("[Lora] Waiting for join (max 120s)...");
BaseType_t result = xSemaphoreTake(join_semaphore, pdMS_TO_TICKS(120000));
vSemaphoreDelete(join_semaphore);
join_semaphore = nullptr;
if (result == pdTRUE) {
if (b_joined) {
Serial.println("[LoRa] Successfully joined TTN");
return true;
} else {
Serial.println("[LoRa] OTAA join failed! Check keys, region and coverage.");
return false;
}
} else {
Serial.println("[LoRa] OTAA join timeout");
return false;
}
}`
This is my sending function, works if i use LMH_UNCOMFIRMED_MSG
`bool sendLoRaPacket(float objectTemp, float avgX, float avgY, float avgZ, float latitude, float longitude, float altitude) {
if (!b_joined) {
Serial.println("[LoRa] Not joined yet - skipping send");
return false;
}
Serial.println("[LoRa] Trying to send data");
// Clean lpp
lpp.reset();
// Convert values into CayenneLPP
// Channel 1: temperature
lpp.addTemperature(1, objectTemp);
// Channel 2: average accelerations
lpp.addAccelerometer(1, avgX, avgY, avgZ);
// Channel 3: GPS location
lpp.addGPS(1, latitude, longitude, (int32_t)(altitude * 100));
// Copy to GLOBAL persistent buffer
memcpy(lora_app_data.buffer, lpp.getBuffer(), lpp.getSize());
lora_app_data.buffsize = lpp.getSize();
lora_app_data.port = LORA_APP_PORT;
Serial.printf("[LoRa] Sending %d bytes...\n", lora_app_data.buffsize);
lmh_error_status error = lmh_send(&lora_app_data, LMH_UNCONFIRMED_MSG); //lmh_send(&app_data, LMH_UNCONFIRMED_MSG);
if (error == LMH_SUCCESS) {
Serial.println("[LoRa] Packet sent successfully");
} else {
Serial.printf("[LoRa] Send failed with error code: %d\n", error);
}
if (tx_semaphore == nullptr) {
tx_semaphore = xSemaphoreCreateBinary();
if (tx_semaphore == nullptr) {
Serial.println("[LoRa] Failed to create TX semaphore!");
}
}
//Wait for tx_finished callback (timeout 15 seconds)
if (xSemaphoreTake(tx_semaphore, pdMS_TO_TICKS(15000)) == pdTRUE) {
Serial.println("[LoRa] TX confirmed complete");
return true;
} else {
Serial.println("[LoRa] TX confirmation timeout - packet may still send");
return false;
}
}`
I'm pretty sure that waiting for the lorawan_tx_finished_handler or using LMH_CONFIRMED when sending triggers the error.
Questions
Is the tx_finished callback intentionally not called for unconfirmed messages in this library version?
Is there a safe way to wait for TX completion without blocking the main thread (to avoid cache disable crash)?
Is there a known workaround or patch for this library to make tx_finished reliable for unconfirmed uplinks?
Beta Was this translation helpful? Give feedback.
All reactions