This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

About timing in mesh processing

Hello team,

I'm working on system development using Mesh SDK and I have some questions so please let me know.

###############
Development environment
IDE : Segger Embedded Stuido
SoC : nRF52840
SDK : Mesh v2.2.0
          normal SDK v15.0.0
Base project : light switch example (modifying for our system)
###############

1. If a node belonging to a group receives a message for that group address, which of the following will be performed first?
    ・Processing for messages, such as replies
    ・Transfer message to another node
    ・Anything else.


2. There is possiblity to rewrite the same variable in the receive callback of Mesh message and the timer interrupt handler, in main.c.
    As such, I do not want to generate other interrupts during this process, includes receiving mesh messages.
    How can I realize this?
    Are the following functions and macros useful?
    ・CRITICAL_REGION_ENTER () / CRITICAL_REGION_EXIT ()
    ・nrf_mesh_disable () / nrf_mesh_enable ()


3. About interrupt
    As far as the document is referred to, when the Mesh message is received during execution of the application interrupt process,
    the application interrupt is interrupted and the Mesh reception interrupt is processed.
    I think that system will return to the interrupted application interrupt after the processing of the reception interrupt is finished.
    Is this recognition correct?

    I will assume that it is correct and ask a question.
    Is there a way to see this series of processes?
    
    I put a loop processing with an end condition to make the waiting time in the timer interrupt handler.
    I tried sending Mesh messages during looping, but the timer interrupt handler was not interrupted by the receipt of Mesh messages.
    On the contrary, mesh message reception interrupt did not occur even after loop termination.
    Does that mean that the system has not received a message?
    Or did the system receive it but did not put the interrupt on hold?

    The code in the timer interrupt handler is described below for reference.

void timer_handler(void * p_context)
{
    __LOG(LOG_SRC_APP, LOG_LEVEL_INFO, "%s called.\n", __func__);
    
    for (uint8_t i = 100; i > 0; i--)
    {
        printf("loop %d\n", i);
    }
}



Thanks in advance.

Wataru

Parents
  • Hi Wataru

    1. First the packet will be decrypted. Then there will be a check to see if it should be relayed, after which the TTL will be decremented, the packet encrypted again, and put in the outgoing packet buffer. 

    After that the packet will be processed locally. 

    Still, depending on the state of the outgoing buffer there might be some delay before the packet is retransmitted, so whether or not this happens before the local processing is impossible to say. 

    2. An interrupt of the same priority as another can not interrupt it. This also means that an interrupt can not interrupt itself. 

    The only thing that can interrupt you when you are in an interrupt handler is another interrupt of higher priority (lower IRQ priority number). 

    If the timer interrupt has a higher interrupt priority than the mesh interrupt then I would suggest disabling this particular interrupt before you access the shared variable. 

    3. If an application interrupt of lower priority is interrupted by the mesh interrupt, then execution will return to the application interrupt after the mesh interrupt is completed, that is correct. An interrupt of similar priority will not be interrupted. 

    You could visualize this by using a debugger with trace functionality, such as the Segger J-Trace.

    Regarding your timer_handler, I expect that this is running at an interrupt priority similar or higher than that of the mesh interrupts, which means you are blocking the mesh operation while sending your messages. This is not recommended, as the mesh will not be able to operate as normal. 

    Maybe you could try to defer the execution to the main context instead, either by using the app_scheduler module, or by setting a flag in the timer_handler that you later check in your main loop?

    Best regards
    Torbjørn

  • Hi, Ovrebekk

    Thanks for your reply. And sorry for the late my reply.

    1. My understanding that the order to execute first is not decided, is it correct?
        (Processing of messages or relaying of messages)

        Even in that case, both processes will be performed?

    2. If an interrupt with the same priority occurs while processing in the interrupt handler,
        will interrupt processing that occurs later be on hold?

        In other words, will interrupt processing that occurs later be executed
        after the current interrupt handler has ended?


    By the way, in the light_example example, what is the priority of mesh interrupts?
    I think the priority is "0". Does that mean not?
    The timer interrupt priority is set to LOWEST (7).

    Although it is not intended, if you can block mesh interrupts,
    do you think that blocking mesh interrupts is not a problem
    if it is an algorithm that can collect data in multiple communications?

    I don't want to do this now because using the app_scheduler is likely to result in many system changes.
    I would like to consider again at the timing of the big update,
    so please inform me about how app_scheduler works and how to use it.

    Best regards
    Wataru

  • Hi,

    Please let me ask another question related to it.

    In the project I wrote,
    How can I check stack memory and heap memory respectively?
    I want to know these addresses and sizes.

    BR,
    Wataru

  • Hi Wataru

    To check the size of your heap and stack you should open the project options in Segger Embedded Studio, select the 'common' configuration, and open the 'Runtime Memory Area' section as shown in the below screenshot:

    Best regards
    Torbjørn 

  • HI, Torbjørn

    Thanks for your reply.

    Is that the information you gave me is the same as the one described in the map file?
    (I attach it below. )


    BTW, can you answer another question on this thread?

    Best regards
    Wataru

Reply Children
  • Hi Wataru

    Yes, that is the same information. If you change the settings in SES and recompile you should see the values in the map file change. 

    "BTW, can you answer another question on this thread?"

    Which question would that be?

    Edit: If you have a new question not directly related I would suggest opening a new thread. In particular since I don't have a lot of experience with the mesh SDK ;)

    Best regards
    Torbjørn

  • HI, Torbjørn

    Thanks for your reply and I'm so sorry for the too late reply.
    I took long vacation...

    I understood that it was the same as the information described in the map file. .
    Thank you very much.

    ###

    "BTW, can you answer another question on this thread?"

    Which question would that be?
    ###

    What I commented on your response to my first question.
    I quote below.

    ###

    1. My understanding that the order to execute first is not decided, is it correct?
        (Processing of messages or relaying of messages)

        Even in that case, both processes will be performed?

    2. If an interrupt with the same priority occurs while processing in the interrupt handler,
        will interrupt processing that occurs later be on hold?

        In other words, will interrupt processing that occurs later be executed 
        after the current interrupt handler has ended?

    By the way, in the light_example example, what is the priority of mesh interrupts?
    I think the priority is "0". Does that mean not?
    The timer interrupt priority is set to LOWEST (7).

    Although it is not intended, if you can block mesh interrupts, 
    do you think that blocking mesh interrupts is not a problem 
    if it is an algorithm that can collect data in multiple communications?

    I don't want to do this now because using the app_scheduler is likely to result in many system changes.
    I would like to consider again at the timing of the big update, 
    so please inform me about how app_scheduler works and how to use it.


    ###

    I think that it is related to my first question, so I do not want to launch a new thread.

    I look forward to your answer.

    Best regards,
    Wataru

  • Hi Wataru

    I hope you had a good vacation Slight smile

    1. Yes, you can't tell for sure if the messages will be relayed or processed first, but both processes will be performed eventually. 

    2. Yes. If you are in an interrupt, and another interrupt at the same priority occurs, the second interrupt will be executed after the first interrupt is completed. An interrupt can only be interrupted by another interrupt that has a higher priority (lower priority number). 

    The mesh interrupts are explained in more detail here

    Essentially the time critical radio interrupts are running at priority 0, which is the highest priority in the system. This ensures that during critical mesh processing the stack will not be interrupted by anything else. 

    Less critical mesh operations run at a lower interrupt priority (higher number), and can even run from the main context, so these interrupts you should be able to block for a while without any ill effects. 

    The app_scheduler library is documented here

    Best regards
    Torbjørn

  • HI, Torbjørn

    Thank you. I was able to spend a nice day off.

    I felt relieved to hear that both the processing for the message
    and the forwarding of the message are performed.


    I understood that if an interrupt occurs while processing the same priority, it will be suspended.
    If for some reason it takes a long time to process the current interrupt,
    can you say the same thing? (Does the pending interrupt be executed after the processing ends?)

    Do you say that in the light_switch example, the callback function (eg, get / set) in main.c is a less important mesh operation?
    If so, there is a slight strange. . .


    Thank you, I will refer to the document about app_scheduler.
    By the way, if you try to port from the method of executing each operation by the interrupt like the sample to the method of using app_scheduler, is it so difficult?

    Best regards
    Wataru

  • Hi Wataru

    "If for some reason it takes a long time to process the current interrupt, 
    can you say the same thing?"

    The pending interrupts won't be forgotten or timed out, if that is what you mean, but if you have very long interrupts in your system it could affect the performance of the mesh. 

    In general I would say it is not recommended to have interrupts lasting for much more than 10-50 milliseconds. 

    "Do you say that in the light_switch example, the callback function (eg, get / set) in main.c is a less important mesh operation?"

    I wouldn't say less important, just less time critical. In most communications protocols the lower levels of the protocol, closer to the physical layer, are more time critical. The higher levels, closer to the application, don't have to be processed right away, but can be processed whenever the CPU has some free time. 

    "By the way, if you try to port from the method of executing each operation by the interrupt like the sample to the method of using app_scheduler, is it so difficult?"

    No, I think using the app scheduler is quite simple. All you have to do is to put the code that you want to schedule into a function, which needs to have the function signature like this:

    void my_app_sched_event_handler_1(void *p_event_data, uint16_t event_size)
    {
    // Your code here...
    }

    Then you use the app_sched_event_put() function to schedule this function to be run, and any data that you provide in the p_event_data and event_size variables will be available to the function once it is run. 

    Best regards
    Torbjørn

Related