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

  • HI, Torbjørn

    Thank you for the reply, I feel that the problem I'm concerned about is gradually solved.

    It turns out that the pending interrupt never disappears.
    So how many interrupts can I hold?
    Is that something defined elsewhere? Can I change it?

    Here is a concrete example.
    When sending messages from five to six edge devices to one gateway device at the same time (as a reply to the message from the gateway), can the gateway receive all messages at once?

    I'm not clear in me if there is a direct relationship with the interrupt ,,,
    Where is message transfer actually done? That functionality is included in the light_switch sample project, right?
    Does a developer need to develop an application that he wants to realize while also being concerned with message transfer processing (timing etc.)? Or is the message transfer process independent of the application, and the developer does not need to worry? Which one?



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

    In other words, at the higher level, like the application layer, is it that the processing priority for messages is set to the lowest value (7)? Like below.

    static void mesh_init(void)
    {
        uint8_t dev_uuid[NRF_MESH_UUID_SIZE];
        uint8_t node_uuid_prefix[NODE_UUID_PREFIX_LEN] = SERVER_NODE_UUID_PREFIX;
    
        ERROR_CHECK(mesh_app_uuid_gen(dev_uuid, node_uuid_prefix, NODE_UUID_PREFIX_LEN));
        mesh_stack_init_params_t init_params =
        {
            .core.irq_priority       = NRF_MESH_IRQ_PRIORITY_LOWEST,
            .core.lfclksrc           = DEV_BOARD_LF_CLK_CFG,
            .core.p_uuid             = dev_uuid,
            .models.models_init_cb   = models_init_cb,
            .models.config_server_cb = config_server_evt_cb
        };
        ERROR_CHECK(mesh_stack_init(&init_params, &m_device_provisioned));
    }
    



    Thank you for providing a simple example of how to use app_scheduler.
    First of all, we will study the specifications while doing a simple experiment to update the system.


    Best regards
    Wataru

  • Hi Wataru

    Each interrupt vector is either pending or not pending, it doesn't track how many times the interrupt occurs. If you suspect that the interrupt could happen multiple times before you have time to process the first one you will have to check at the end of the interrupt if there is any more data to process before leaving the interrupt. 

    Typically this would be implemented by pushing the relevant event data into a FIFO buffer before setting the interrupt pending. Then you can check the state of the FIFO buffer at the end of the interrupt handler, and if the interrupt happens multiple times before you are able to process it you will have to run through all the items in the FIFO. 

    When using this approach the number of interrupts you can 'hold' is set by the size of the FIFO (how many elements can the FIFO hold). 

    "Where is message transfer actually done? "

    You mean the physical message transfer over the air?

    This is handled by the lower layers of the mesh implementation, which is included for you by the light_switch example. The application should not have to worry about this, as long as you don't try to push more data through the mesh than it can handle. 

    "In other words, at the higher level, like the application layer, is it that the processing priority for messages is set to the lowest value (7)? Like below."

    Interrupts for the application are running at the lowest priority, yes, which means they might be delayed by higher priority interrupts in the lower parts of the mesh stack. This is done to make sure that the processing of mesh events in the application will not affect or delay the time critical mesh operations happening in the stack. 

    Best regards
    Torbjørn

  • HI, Torbjørn

    I'm sorry for my late reply.

    I understand that the interrupt vector only has a status of pending or not.
    By the way, can the status of the interrupt vector be checked by outputting it in LOG during processing?
    In the systems we operate, it has been found that, very rarely, timer interrupts do not occur at the expected time.
    In order to prove this, I want to know the state of the vector table and so on.
    Alternatively, please let me know at the same time if there are other registers useful for debugging.


    Yes, It is a physical transfer by radio.
    There seems to be no problem with message hoping.
    I do not intend to process the contents of the relay message payload.


    I also understood the priority of mesh processing in the main application.
    I was a little surprised at the lowest priority, but it does not interfere with the time critical processing of lower layers.


    Best regards
    Wataru

  • Hi Wataru

    Are you able to connect your kit to an oscilloscope?

    Then you can toggle a pin at the start and end of the interrupt vector, and use the oscilloscope to monitor when the interrupt triggers, and how long it runs. 

    While a bit primitive, this is a very non intrusive and reliable way to measure the interrupt activity. Writing to the log can be quite slow, and might not be able to keep up with the interrupt activity. 

    Best regards
    Torbjørn

  • Hi Torbjørn

    It is possible to connect to an oscilloscope.
    Are you saying to toggle any GPIO when an interrupt occurs?
    If possible, I would like to check the register of each interrupt directly. . .
    Is it impossible to make it with logs?

    I think that the some delay may be tolerance to knowing the status of the interrupt register in software..
    By the way, can you give us information about which register to look at? I would to know this information at least.



    BTW, as I mentioned earlier that no timer interrupt has occurred, is the possibility of my misunderstanding.
    I was doing each processing in a fixed cycle, but rearly, I had not had an event that should have happened on a rare cycle so I judged.

    But, The time stamp output from the LOG in the timer interrupt handler proved that it was operating at the intended interval.

    Is there a possibility that this information (timestamp) is unbelievable?
    If so, I think that means that RTC sometimes stops.

    It has not yet been confirmed that the operation cycle of one timer in the system was correct.
    But I have a question.
    Does it happen occasionally that the timer interrupt generation cycle deviates from the intended one?

    Best regards,
    Wataru

Related