FreeRTOS+ TCP, identifying "pNetworkInterface"

This is so embarrassing. After I’ve inited the TCP interface and it’s going I need to start a mqtt connection. But I need to pass an “pNetworkInterface” to establish a connection. This is how i start the connection.

FreeRTOS_IPInit(ucIPAddress, ucNetMask, ucGatewayAddress, ucDNSServerAddress, ucMACAddress);

Then i wait for dhcp to get an address and i need to call

int RunMqttDemo( bool awsIotMqttMode,
const char * pIdentifier,
void * pNetworkServerInfo,
void * pNetworkCredentialInfo,
const IotNetworkInterface_t * pNetworkInterface )
{

How can i link the tcp connection i just made to an "IotNetworkInterface_t "

It’s got to be right under my nose but i can’t find it.

Thanks in advance.

Are you using the latest release candidate MQTT stack? This one: https://www.freertos.org/mqtt_lts/index.html ? If so there is a demo here: https://www.freertos.org/mqtt_lts/preconfiguredexamples.html that is using FreeRTOS+TCP so the network interface will basically be the same unless you want to use TLS too. If you want to use TLS then you will have to update just the network interface files. (if this is a production device then it is strongly recommended to use TLS!). This is the implementation. I think only the send and receive functions are really needed - the others are in there for convenience. https://github.com/FreeRTOS/FreeRTOS/blob/lts-development/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries-LTS-Beta2/c_sdk/platform/freertos/transport/src/plaintext_freertos.c

Addition to the above - if that is the code you are doing - then the network interface requirements have not been documented yet, although they will be before the LTS release is finalised - so its not that embarrassing :wink:

Doh! I didn’t even see that and used the old library that is on the same page. Suggestions? I took me a while to bring in the correct files for the previous lib. Should I update to this new one? I have to use TLS which there is an example of here. https://www.freertos.org/mqtt/preconfiguredexamplesTLS.html
That’s the example i’ve been trying to go by.
Are you saying this library is no good? Can i use TLS using the new send and receive method? Can anyone point to a more noob example i could follow. I’d like to try that example if i could just figure out how to initialize it.

Thanks again.

That library is part of our LTS roadmap - we are refactoring them to make them smaller, more optimized, and in particular decoupled to make this:

much easier. The optimised version I linked to doesn’t have any dependencies other than on the C library and the network interface.

The network interface as per the link in my previous post provides the send and receive functions. It is an interface specification really. This is the interface specification header file: https://github.com/FreeRTOS/FreeRTOS/blob/lts-development/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries-LTS-Beta2/c_sdk/platform/include/transport_interface.h . Within that file (links correct at the time of writing) this is the interface for the receive function https://github.com/FreeRTOS/FreeRTOS/blob/lts-development/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries-LTS-Beta2/c_sdk/platform/include/transport_interface.h#L45 and this is the interface for the send function https://github.com/FreeRTOS/FreeRTOS/blob/lts-development/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries-LTS-Beta2/c_sdk/platform/include/transport_interface.h#L58

So you need to have an implementation of those two functions. Currently we have implementations for Linux using OpenSSL for its TLS, and FreeRTOS+TCP without any TLS so far. You can update the FreeRTOS+TCP version (link in my previous post) to add in TLS. Eventually we will have a library of these different combinations, but we are not there yet.

You can also create the network send and receive function by re-using the network code from the project you linked to yourself, you would ‘just’ need to wrap the function so they have the prototype from the network interface specification above Example MQTT client application with TLS server authentication for microcontroller IoT devices - FreeRTOS because that project is already using FreeRTOS+TCP with mbedTLS. The network files in that case are here: https://github.com/FreeRTOS/FreeRTOS/blob/lts-development/FreeRTOS-Plus/Source/FreeRTOS-IoT-Libraries-LTS-Beta1/abstractions/platform/freertos/iot_network_freertos.c.

I’m sure that will generate more question, let me know…

Trying that new version and i’ve almost got it. I can establish a connection with the server but no packets go through the socket though. I think. I’m just running the demo example from the beta 2 example with the details changed to my server. If I wire shark it it’s fine until this line.
prvCreateMQTTConnectionWithBroker. This is the first time it try’s to use the socket interface - it goes down like this;
xResult = MQTT_Connect( pxMQTTContext… ->
bytesSent = sendPacket( pContext… ->
bytesSent = pContext->transportInterface.send( pContext…->
socketStatus = FreeRTOS_send( pNetworkContext…->

That is where the problem is for me FreeRTOS_Sockets.c - FreeRTOS_send - line 2747
This completes and returns a value of 18 bytes sent. However if i monitor my network driver, spi, and wireshark. nothing is actually sent. My driver must be good though because up to this point i’ve DHCP’d, DNS’d and established the socket. This is all pretty new to me so i might be not understanding how it works.

Thanks in advance.

If you are seeing DHCP and DNS traffic then it is curious you would not see the socket traffic. Do you get the IP address from the DHCP server? Do you also get a gateway address from the DHCP server? What are they? What is your target microcontroller?

I have to rush this post before i run out the door. Here are the different paths it takes.
image

image

Sorry i don’t have time for anymore info now. Looks like one creates an event and the other doesn’t?

Sorry i lie. they both end up here.
image
image

But the frame is never sent by the ip stack when it comes to connecting to the broker. although the packets that do get set are sent as a “eNetworkTxEvent” The packets that are never sent are passed down as a “eTCPTimerEvent” I’ll keep trying to get more info to narrow it down for you guys.
Thanks so much for your patience.

This kind of remote debugging is always complicated, because we can not see the whole picture.

What I can say is that when FreeRTOS_send() returns 18, it means that 18 bytes have been copied onto the internal TX buffer. The IP-task will be woken up and try to send the data.

There are no known issues with using FreeRTOS_send().

All I can recommend is making sure you’re using a recent release of all software, have configASSERT() defined, check for stack-overflow, make sure that there is enough heap, enough free network buffer, make sure the IP-task gets CPU-time, make sure that the Internet path to the remote server is OK.

I recently wrote a function vPrintResourceStats() in FreeRTOS_IP.c. Depending on the platform, it will be called from NetworkInterface. That function will check some essential resources.

Sorry to be a pain, just trying to figure out how this part works and I tend to post a lot for the sake of the next beginner on the forum. In FreeRTOS_Sockets.c I find this at line 2811


Here is where it puts the mqtt connect cmd stream is put into the buffer and then calls “eTCPTimerEvent”, I can see that this timer event is picked up in the FreeRTOS_IP.c loop. But from here I can’t see where the packet is processed. I assume there is some sort of buffer queue somewhere that is scanned for events to be processed but i can’t find it. I’m keen to find out why the stream never hits the driver. One thing i will note because it might be relevant is that when FreeRTOS_sendto is called to make the socket - the outgoing port for the tcp socket is xxxxx but when the stream buffer is created by plaintextdemo->FreeRTOS_send the outgoing port is yyyyy. If the mqtt example is trying to send to the previously created socket. don’t they need to be the same?

Thanks for patience.

AHHHHHHHHHHHH!
OK I’ve done what i should have done at the start and installed vs2019 and ran the demo project. I set them up the same as much as i could. Obviously different network drivers though. Of course the demo worked fine. So i stepped through the demo code side by side with my stm32 code until i noticed a difference. at line 669 of “FreeRTOS_TCP_IP” “prvTCPPrepareSend” always returns 0 on my micro controller but returns a value in the demo on windows. That’s as far as i can get tonight. Sorry to give you all the run around. I’m very grateful.

OK, fixed! “static BaseType_t prvCreateSectors” returned a pdfail when it failed to allocate xtcpsegments. Yes, this is because i was out of heap. I didn’t look into this because i assumed what wasn’t stack was heap and i have a ton of spare memory. I didn’t realize that the heap was stactic and defined at startup. the tcp list always returned zero because of that failure of allocation at the start. you may begin your ridicule now. :frowning: Still learning. Thanks again.

I’m sorry to answer so late, I didn’t recognise your post as a FreeRTOS+TCP problem because I saw several times MQTT.

I assume there is some sort of buffer queue somewhere that
is scanned for events to be processed but i can’t find it

The TCP/IP stack is run from a task called prvIPTask(). It receives messages from a queue called xNetworkEventQueue. It is recommended to give the IP-task a priority that is higher than the tasks that make use of the +TCP library. So when an API returns, the IP-stack will have handled the message already.

But you solved your problem, great! You’re not the first person running out of heap space.
I hoped that these things can be detected earlier since PR #2164: “FreeRTOS+TCP : print resource statistics routine”.

i assumed what wasn’t stack was heap

Often that is a good assumption. But for ease of use, most demo applications use heap_4.c, which has a fixed size determined at compile-time.
I always like to use heap_5.c, which allows a dynamic configuration at runtime. Once running you know where the (initial) stack ends, and you also know the size of data/bss.
Here is a description: FreeRTOS +TCP on SAME70 - #7 by htibosch

About FreeRTOS_sendto() and FreeRTOS_send(): in FreeRTOS+TCP the former is used for UDP sockets, and the latter (send()) is only used for TCP.
There are two independent ranges of port numbers: one for UDP and one for TCP. Normally there is no relation between these ports.
Under TCP, 80 and 8080 are typically HTTP port numbers. Under UDP they may have a totally different function.
The port numbers 0 to 1023 are reserved for the system, other port numbers are free to use, although there will be quite a few reserved numbers as well. See also socketAUTO_PORT_ALLOCATION_START_NUMBER which defaults to 1024.