This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

RTOS: Design Pattern request for Blocking Sockets (MQTT)

Other Parts Discussed in Thread: EK-TM4C129EXL

Tool/software: TI-RTOS

Dear Community,

I have the following problem that I would like to solve somehow. (RTOS is the latest, and the device is EK-TM4C129EXL) 

The uC has different threads that deals with ADC and other IO port management. The ADC generating data and IO is receiving jobs from the outer world. In order to interact with the device MQTT protocol is selected for the latest release but in the previous one, I had a standard TCP/IP protocol with custom packet format. The problem that I would like to handle is how to manage the network communication with the inter thread communication without losing significant time pending on Mailboxes or blocking socket operation.

In the previous design I had a connected socket I shared that in two tasks one is for reading and the other for sending data. The model looks like this one:

socketReaderThread{

 // blocking socket read operation
 int count = recv(sharedSocket, ..., ...);
 
 // send the request to the right Task based on the request code
 Mailbox_post(myTaskMailbox, request, BIOS_WAIT_FOREVER);

}

socketSenderThread{
 
 // waiting for any task response 
 Mailbox_pend(myTaskMailbox, taskResponse, BIOS_WAIT_FOREVER);

 int count = send(sharedSocket, ..., ...);

}

The solution above has a huge advantage, I can send and receive messages immediately as they occurred. 

Now I would like to update the communication for MQTT  and I have ported the paho C example code ( MQTTPacket) to TI RTOS and here is my problem:

while(1){

 // wait for task response, and handle BIOS_NO_WAIT
 if(Mailbox_pend(myTaskMailbox, mbResponse, BIOS_NO_WAIT)){
   
   mqtt_pub(socket, mbResponse, ...)
 }

 // this call blocks the entire task
 mqtt_sub(socket, sub_buffer, ...);

 
}

In the above code the mqtt_sub blocking the entire task based on SO_RCVTIMEO parameter. According to my understanding the value of SO_RCVTIMEO should be large enough to wait for PUB_ACK for my PUB request. (Handle network uncertainty) But 1 second is very long time to block my whole task.

How can I achieve that not to block so long on mqtt_sub?

I don't think that changing the SO_RCVTIMEO is the key for my problem.... 

Looking forward you kind reply.

PS.: I have implemented a solution where the uC makes 2 mqtt client connection one for publish and one for subscribe. That works very well, but this model results two mqtt clients with duplicated auth, client_id, and displayed as two device in an IoT platform.

 Update: I think the non blocking implementation of mqtt for TM4C would be the best. But As I saw there is none. 

  • Daniel,

    Our recent software releases have had some internal changes to our network stack. It is important to know precisely which release you are using. For the EK-TM4C129EXL, we have the following release:

    TI-RTOS TivaC 2.16.01.14
    NS 1.11.00.10
    NDK 2.25.00.09

    Please confirm if this is what you are using.

    From where did you get the MQTT implementation? Is it from TI software or is it coming from a third party?

    From your description, you have a task (consumer) which is blocked on a call to mqtt_sub() (with a one second timeout). But you would like this task to return immediately when there is new data in the mailbox. This should happen even if there is no data on the socket. Correct? In addition, I assume you have  another task (producer) which is placing new data into the mailbox. Have I got this correct?

    One idea is to use localhost (127.0.0.1) to communicate between the two tasks. In your consumer task, open a socket to localhost for reading. Before calling mqtt_pub(), call select() with both sockets (localhost, mqtt). When select() returns, use the readfds to determine which socket has data. In your producer task, open a socket to localhost for writing. After this task has put new data into the mailbox, write to the localhost socket. This should wake up immediately the consumer task waiting in select().

    What do you think of this idea?

    ~Ramsey

  • Dear Ramsey,

    Thank you for your answer. The following versions I have:
    RTOS 2.16.0.08 and the ns and the ndk are the same because there are in the folder in the tirtos_tivac_2_16_00_08\products. I suppose this version is used in my project.

    I am using eclipse paho mqtt implementation (www.eclipse.org/.../ ) however I would like to use mqtt lib from SimpleLink. I have checked the mqtt example with the MSP432 ethernet launchpad and I really liked that implementation. (RTOS based and uses callbacks for sub.) I tired to port simplelink mqtt to TM4C RTOS project but I failed. I think I will start a new thread to ask for help.

    You understand my problem well.

    I do really like your idea. It worth a try.
    1. Do you have an example or something that I could use?
    2. Do you think that SimpleLink mqtt can be used in TM4C?
  • Daniel,

    I'm sorry, but I don't have any code examples to share. If I come across something, I'll post it.

    I think it would be a significant effort to back port SimpleLink MQTT to TI-RTOS on Tiva C. We made some significant changes to our network stack implementation from TM4C to MSP432 The MQTT layer requires the latest network changes.

    Would it be possible for you to move forward to MSP432E4? The SimpleLink software has some good improvements in the EMAC driver as well.

    ~Ramsey

  • Hello Daniel,

    Do you need any more support on this thread?

    The SimpleLink SDK is not supported on TM4C devices. As Ramsey has pointed out it might be a lot of work to back port the MQTT library in the SimpleLink SDK to TI-RTOS for TivaC package.

    Thanks,
    Sai
  • Dear Ramsey,

    We have moved to the MSP432 platform and porting our code to the new platform. Thank you for your suggestion and sorry for my late reply!