Menu

MSTP Slave Only Device

Jason
2016-02-17
2016-02-17
  • Jason

    Jason - 2016-02-17

    I was wondering if there has been any recent discussion on adding a slave only section to the MSTP section of the BACnet stack.

    I have a product which uses the stack in an embedded device on a Microchip PIC24 platform. Unfortunately due to the speed of PIC24 and its ability to write to the graphical display, we can only gaurentee entry into the BACnet stack every 100ms. Obviously this causes some issues (given that we need to reply to the master frams within 15ms) and so we have made the difficult decision to run the stack from within an interrupt that is called every 5ms. We have taken a variety of precautions to ensure that it works safely and have been successful with it, but it still leaves that lingering feeling of did we account for everything.

    We were looking at the BACnet protocol and unless we are mistaken, believe that switching to slave only would allow us to call the stack every 100ms provided that the stack responds with the requested data message right away instead of sending a response postponed message.

    Are there any plans to provide a slave only option? If not, is there a framework that I could follow to make the conversion myself? I have seen the question asked quite a few times and am hoping to get movement going to improve the functionality of the stack.

    Thanks,
    Jason

     
  • Steve Karg

    Steve Karg - 2016-02-17

    I have done several BACnet MS/TP products that use a 5ms timer interrupt to drive the MS/TP state machine, but I separate the data received and data to be sent into queues (ringbuffers) that are serviced by the main loop at a later time:

    void bacnet_task_timed(
        void)
    {
        ...
        pdu_len = dlmstp_receive(&src, &PDUBuffer[0], sizeof(PDUBuffer), 0);
        if (pdu_len) {
            pkt = (struct mstp_rx_packet *) Ringbuf_Data_Peek(&Receive_Queue);
            if (pkt) {
                memcpy(pkt->buffer, PDUBuffer, MAX_MPDU);
                bacnet_address_copy(&pkt->src, &src);
                pkt->length = pdu_len;
                Ringbuf_Data_Put(&Receive_Queue, (uint8_t *)pkt);
            }
        }
        ...
    }
    
    void bacnet_task(
        void)
    {
        ...
        if ((!dlmstp_send_pdu_queue_full()) &&
            (!Ringbuf_Empty(&Receive_Queue))) {
            Ringbuf_Pop(&Receive_Queue, (uint8_t *)&pkt);
            npdu_handler(&pkt.src, &pkt.buffer[0], pkt.length);
        }
        ...
    }
    

    As for slave node state machine, there are several examples - search for a function named MSTP_Slave_Node_FSM() in all the files.
    bacnet-stack\ports\atmega8\dlmstp.c
    bacnet-stack\src\mstp.c

     
  • Jason

    Jason - 2016-02-17

    Hi Steve,

    Correct me if i'm wrong, but you only handle the master functions in the timer interrupt and anything that isn't, you just put in a receive queue and wait until you get around to it later.

    As for the slave node, my appologies for asking an already answered question. I missed it because I was using the PIC18 port (because we were upgrading from a 0.5.7 and it also used the PIC18 port) and that port only has the master example in it.

    Thanks for your help.
    Jason

     

Log in to post a comment.