[riot-users] Radio Interrupt Handler

Joakim Nohlgård joakim.nohlgard at eistec.se
Fri Nov 9 18:00:25 CET 2018


Hi again Navneet,

Den fre 9 nov. 2018 12:20 skrev Navneet Pandey <navneet.pandey at outlook.in>:

> Hello Joakim, thanks for an elaborate explanation, I will check those
> articles out. Before I do, I have a few more queries.
>
>
>
> Could you also point out which module is responsible for radio switch
> on/off, assuming radio only has a binary mode unlike the CPU.
>
> Is it ‘at86rf2xx_netdev’ or something else?
>
Yes, look for the NETOPT_STATE handler in that file (_set_state)

>
>
> Also, is it possible to keep the radio open always for the duration of an
> experiment? And may be avoid deep sleep mode as well?
>
What you describe is the default behavior of the gnrc_networking example,
no configuration necessary. The radio will be initialized and set to listen
for incoming traffic, and will remain turned on until you type ifconfig x
set state sleep in the shell. To disable the CPU power savings, the easiest
way is to either disable the pm_layered module using
DISABLE_MODULE=pm_layered on the command line with your make command, or
change the initial pm_blockers to non-zero. The pm blocker initial value is
found in cpu_conf.h, or cpu_conf_common.h

>
>
> And am I correct when I say that ‘cortex_sleep(deep)’ puts CPU to sleep
> but doesn’t touch the radio (based on what you replied).
>
Yes, that is correct.

>
>
> Based on some of the modules on which I enabled debugging:
>
> Following was the pattern:  PACKET SENT-> TX_Ends -> pm_set_lowest -> Idle
> -> pm_set_lowest -> RX_Ends -> PACKET RCVD.
>
> I did not understand the part where CPU moved to idle state before going
> to sleep again. Did I miss any state in the process (probably did not
> enable debugging)?
>
Yes, you missed the interrupt sent from the radio to the CPU.
The CPU is awoken by an interrupt from the radio. The radio has a signal
named INT or similar that is connected to an input pin on the CPU. When the
radio receives an incoming frame from somewhere, the radio will toggle the
interrupt pin to signal that it wants to be serviced by the driver. The
interrupt on the CPU is configured to wake the CPU from low power modes.
Look for _irq_handler in at86rf2xx_netdev.c.
The IRQ handler in that file only posts an event to the gnrc_netif thread
telling it that it needs to poll the radio to see what the reason for the
interrupt is, this usually means reading some status register in the radio.
That last part is performed by the _isr function in at86rf2xx_netdev.c

The first transition from pm set lowest to idle could be a RX Begin event,
and the second wake could be the RX End interrupt. The RX Begin interrupt
is sent when only the first byte of the frame has been received. The RX End
interrupt is sent when the frame has been completely received. Without more
info I can only guess.


>
> I know these are a lot of questions. I really appreciate that you are
> answering my question in great detail. Thank you.
>
>
>
> Regards,
>
> Navneet Pandey
>
>
>

Best regards, Joakim

> *From:* Navneet Pandey <navneet.pandey at outlook.in>
> *Sent:* Thursday, November 8, 2018 1:08 PM
> *To:* users at riot-os.org
> *Subject:* RE: Radio Interrupt Handler
>
>
>
> Hello Joakim,
>
>
>
> Thank you, the information was really helpful. I was exploring the
> ‘at86rf2xx_netdev.c’ file. I noticed something weird. When I enabled
> debugging all I got was
>
>    - To Idle state
>    - Evt TX_END
>    - Evt RX_END
>
>
>
> By enabling debugging in pm_layered.c and pm.c, I noticed
> cortex_sleep(deep) was being called when radio was not doing anything. So
> why am I not seeing any of the following debug statements being printed (or
> in other words none of the following cases being invoked).
>
> case NETOPT_STATE_STANDBY:
>
>             DEBUG("STANDBY\n");
>
>             at86rf2xx_set_state(dev, AT86RF2XX_STATE_TRX_OFF);
>
>             break;
>
>         case NETOPT_STATE_SLEEP:
>
>             DEBUG("To SLEEP\n");
>
>             at86rf2xx_set_state(dev, AT86RF2XX_STATE_SLEEP);
>
>             break;
>
>         case NETOPT_STATE_IDLE:
>
>             DEBUG("To IDLE\n");
>
>             at86rf2xx_set_state(dev, AT86RF2XX_STATE_RX_AACK_ON);
>
>             break;
>
>
>
> Regards,
>
> Navneet Pandey
>
>
>
> *From:* Navneet Pandey <navneet.pandey at outlook.in>
> *Sent:* Monday, November 5, 2018 11:10 AM
> *To:* users at riot-os.org
> *Subject:* Radio Interrupt Handler
>
>
>
> Hello,
>
>
>
> Could someone please point out the code where radio is switched on/off
> when sending a MAC/UDP packet.
>
>
>
> I am expecting something similar to the following code snippet:
>
> /** Turn the MAC layer on. */
>
>   int (* on)(void);
>
>
>
>   /** Turn the MAC layer off. */
>
>   int (* off)(int keep_radio_on);
>
>
>
> This code is from Contiki.
>
>
>
> I am interested in understanding the time it takes for system to wake up
> from sleep (dormant mode) to receive packets.
>
>
>
> Thank you.
>
>
>
> Regards,
>
> Navneet Pandey
>
>
> _______________________________________________
> users mailing list
> users at riot-os.org
> https://lists.riot-os.org/mailman/listinfo/users
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.riot-os.org/pipermail/users/attachments/20181109/c3708547/attachment-0001.html>


More information about the users mailing list