Lora-net / LoRaMac-node

Reference implementation and documentation of a LoRa network node.
Other
1.87k stars 1.09k forks source link

Implement RTOS-friendly IRQ notifiy mechanism #1298

Open maxgerhardt opened 2 years ago

maxgerhardt commented 2 years ago

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.

MohammedBENHADINE commented 2 years ago

@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.