LoRaMac-node
LoRaMac-node copied to clipboard
Implement RTOS-friendly IRQ notifiy mechanism
For the SX126x radios, the IRQ handler installed via
https://github.com/Lora-net/LoRaMac-node/blob/24d55f6319b11104ba1ebb0317244418bb68bd81/src/boards/NucleoL476/sx1261mbxbas-board.c#L74-L77
just points to handler that toggles a boolean flag
https://github.com/Lora-net/LoRaMac-node/blob/24d55f6319b11104ba1ebb0317244418bb68bd81/src/radio/sx126x/radio.c#L1245-L1248
which is later processed in RadioIrqProcess
https://github.com/Lora-net/LoRaMac-node/blob/24d55f6319b11104ba1ebb0317244418bb68bd81/src/radio/sx126x/radio.c#L1250-L1258
Thus, unlike for SX127x radios where work is done more directly in the interrupt handler itself, after an occurance of the interrupt, other code has to call into the Radio.RadioIrqProcess()
function.
In the example apps this is done with a while(1)
loop that continuously calls into the IrqProcess handler
https://github.com/Lora-net/LoRaMac-node/blob/24d55f6319b11104ba1ebb0317244418bb68bd81/src/apps/LoRaMac/periodic-uplink-lpp/NucleoL152/main.c#L302-L308
https://github.com/Lora-net/LoRaMac-node/blob/24d55f6319b11104ba1ebb0317244418bb68bd81/src/apps/LoRaMac/common/LmHandler/LmHandler.c#L350-L358
This is however not nice for RTOS-based and power-saving applications. There, an IRQ interrupt would wake up a thread to process the IRQ only when it is needed, and not check continously on it. In our RTOS-based application we have solved this by inserting a "mid-level handler" for the DIO1 interrupt that after processing the originally (saved) wanted interrupt function (that just sets the flag) triggers a task to wake up and do the actual IRQ process.
Other people have repeated this in different ways: https://github.com/FreeRTOS/Lab-Project-FreeRTOS-LoRaWAN/blob/master/FreeRTOS-LoRaMac-node-v4_4_4.patch#L100
It would be nice if the stack had built-in capabilities for this IRQ -> notify RTOS task mechamism so that we don't have to insert weird mid-level handlers.
@maxgerhardt Waw , i just came across your post after finishing a weird mid-level handler ^^'. I had to setup a software timer in init time , and once the IRQ is triggered from dio0 , i start the software timer with a timeout of 20us (the minimal value i can setup , restriction by the software timer I'm using , the one on ESP32). Then in the callback of the software timer , i pull the original handler (SX1276OnDio2Irq in my case). A weird workaround indeed.